diff --git a/database.go b/database.go
new file mode 100644
index 0000000..7184cee
--- /dev/null
+++ b/database.go
@@ -0,0 +1,45 @@
+package main
+
+import (
+    "gorm.io/driver/sqlite"
+    "gorm.io/gorm"
+	"log/slog"
+) 
+
+type ArtistProfile struct {
+    gorm.Model
+    SpotifyID string `gorm:"unique"`
+    Name string
+    Popularity int
+    Genres []Genre `gorm:"many2many:artist_genres;"`
+}
+
+type Genre struct {
+    gorm.Model
+    Name string `gorm:"unique"`
+}
+
+func setupTestDatabase(name string) *gorm.DB  {
+	slog.Info("[GOMUSIC] Setting up new test database in memory")
+	// Open a named DB instance so each test has a clean environment
+	db, err := gorm.Open(sqlite.Open("file:test1?mode=memory&cache=shared"), &gorm.Config{})
+	if err != nil {
+		panic("Failed to open database")
+	}
+
+	// Run model migrations here to keep DB consistent
+    db.AutoMigrate(&ArtistProfile{}, &Genre{})
+	return db
+}
+
+func setupDatabase() *gorm.DB  {
+	slog.Info("[GOMUSIC] Setting up database and running auto migrations")
+	db, err := gorm.Open(sqlite.Open("gomusic.db"), &gorm.Config{})
+    if err != nil {
+    	panic("Failed to open database")
+    }
+
+    // Run model migrations here to keep DB consistent
+    db.AutoMigrate(&ArtistProfile{}, &Genre{})
+    return db
+}
diff --git a/databse.go b/databse.go
deleted file mode 100644
index 22ebb8a..0000000
--- a/databse.go
+++ /dev/null
@@ -1,39 +0,0 @@
-package main
-
-import (
-    "gorm.io/gorm"
-    "gorm.io/driver/sqlite"
-) 
-
-type ArtistInfo struct {
-    gorm.Model
-    Name string
-    Popularity string
-    SpotifyID string
-    ArtistGenre ArtistGenre
-}
-
-// Stores an association between several Genres and an individual artist
-type ArtistGenre struct {
-    gorm.Model
-    Genres []Genre
-    ArtistInfoID uint
-}
-
-type Genre struct {
-    gorm.Model
-    Genre string
-    ArtistGenreID uint
-}
-
-func setupDatabase() *gorm.DB  {
-    db, err := gorm.Open(sqlite.Open("gomusic.db"), &gorm.Config{})
-    if err != nil {
-    	panic("Failed to open database")
-    }
-
-    // Run model migrations here to keep DB consistent
-    db.AutoMigrate(&ArtistInfo{}, &ArtistGenre{}, &Genre{})
-
-    return db
-}
diff --git a/main.go b/main.go
index e4735d9..e9ddd16 100644
--- a/main.go
+++ b/main.go
@@ -2,25 +2,29 @@ package main
 
 import (
     "github.com/gin-gonic/gin"
-    "os"
+    "gorm.io/gorm"
     "log/slog"
+    "os"
 ) 
 
+// Environment type is used with route methods
+// So that we can easily inject/contain context data like DB connections
+type Env struct {
+	db *gorm.DB
+}
+
 // Grab some required spotify credentials from the environment
 var spotifyClientID = os.Getenv("SPOTIFY_ID")
 var spotifyClientSecret = os.Getenv("SPOTIFY_SECRET")
 
-// Make sure the DB is in a good state to launch
-var db = setupDatabase()
-
-func setupRouter() *gin.Engine {
+func setupRouter(env *Env, spotifyID string, spotifySecret string) *gin.Engine {
     var r *gin.Engine = gin.Default()
-    
-    // Add middleware to handle spotify auth for us
-    r.Use(spotifyAuth(spotifyClientID, spotifyClientSecret))
-    
-    r.GET("/ping", ping)
-    r.GET("/artists/:artistID", getArtistByID)
+	
+	// Add our spotify auth middleware
+	r.Use(spotifyAuth(spotifyID, spotifySecret))
+
+    r.GET("/ping", env.ping)
+    r.GET("/artists/:artistID", env.getArtistByID)
     return r
 }
 
@@ -33,7 +37,10 @@ func main() {
         slog.Warn("[GOMUSIC] No Spotify secret configured in 'SPOTIFY_SECRET' environment variable")
     }
 
-    // Router and server setup
-    r := setupRouter()
+	var db = setupDatabase()
+	env := &Env{db: db}
+    
+	// Router/middleware and server setup
+    r := setupRouter(env, spotifyClientID, spotifyClientSecret)
     r.Run(":8080")
 }
diff --git a/routes.go b/routes.go
index 8747169..1d2e085 100644
--- a/routes.go
+++ b/routes.go
@@ -2,82 +2,55 @@ package main
 
 import ( 
     "github.com/gin-gonic/gin"
+	"gorm.io/gorm/clause"
     "net/http"
     "log/slog"
-    "encoding/json"
-    "fmt"
-    "io"
 )
 
-type SpotifyResponse struct {
-       ID string
-       Name string
-       Popularity int
-       Genres []string
-}
-
-
-func ping(c *gin.Context) {
+func (env *Env) ping(c *gin.Context) {
     c.String(http.StatusOK, "pong")
 }
 
-func getArtistByID(c *gin.Context) {
+func (env *Env) getArtistByID(c *gin.Context) {
     artistID := c.Params.ByName("artistID")
     spotifyAuthToken := c.GetString("spotifyAuthToken")
-
+	
     if artistID == "" || spotifyAuthToken == "Bearer " {
 		c.JSON(http.StatusBadRequest, gin.H{"Error": "Could not find required parameters and/or required authentication tokens"})
-	return
+		return
     }
 
-    // Make a request to spotify API to grab artist data
-    artistEndpoint := fmt.Sprintf("https://api.spotify.com/v1/artists/%s", artistID)
-    req, err := http.NewRequest("GET", artistEndpoint, nil)
-    if err != nil {
-		slog.Error("[GOMUSIC] Failed to build HTTP request", "Error", err)
-	c.JSON(http.StatusInternalServerError, gin.H{"Error": "Failed to request latest spotify data"})
-	return
-    }
-    req.Header.Add("Authorization", spotifyAuthToken)
-
-    // Send off request
-    resp, err := http.DefaultClient.Do(req)
-    if err != nil {
-		slog.Error("[GOMUSIC] Failed to get artist data from spotify API", "Error", err)
-	c.JSON(http.StatusInternalServerError, gin.H{"Error": "Failed to request latest spotify data"})
-	return
-    } else if resp.StatusCode != 200 {
-		slog.Error("[GOMUSIC] Failed to get artist data from spotify API", "Error", resp.Status)
-	c.JSON(http.StatusInternalServerError, gin.H{"Error": "Failed to request latest spotify data"})
-	return
-
-    }
-    respData, err := io.ReadAll(resp.Body)
-    if err != nil {
-		slog.Error("[GOMUSIC] Failed to read response data from spotify API", "Error", resp.Status)
-	c.JSON(http.StatusInternalServerError, gin.H{"Error": "Failed to request latest spotify data"})
-	return
-
-    }
+	spotifyResponse, err := getSpotifyArtistData(artistID, spotifyAuthToken)
+	if err != nil {
+		slog.Error("[GOMUSIC] Failed to request latest spotify data from API", "Error", err)
+		c.JSON(http.StatusInternalServerError, gin.H{"Error": "Failed to request the latest data from spotify API"})
+		return
+	}
     
-    // Close this immediately since it's unused now
-    resp.Body.Close()
+	// Update DB here
+	var genreList []Genre
+	for _, val := range spotifyResponse.Genres {
+		genreList = append(genreList, Genre {Name: val})
+	}
 
-    var spotifyResponse SpotifyResponse
-    err = json.Unmarshal(respData, &spotifyResponse)
-    if err != nil {
-        slog.Error("[GOMUSIC] Failed to read response body data from spotify", "Error", err)
-	c.JSON(http.StatusInternalServerError, gin.H{"Error": "Failed to request latest spotify data"})
-	return
-    }
-    
-    // Update DB here
-    //value, ok := db[artistID]
-    //if ok {
-    //    c.JSON(http.StatusOK, gin.H{"artistID": artistID, "value": value})
-    //} else {
-    //    c.JSON(http.StatusOK, gin.H{"artistID": artistID, "status": "no value"})
-    //}
+	artistProfile := ArtistProfile{
+		SpotifyID: spotifyResponse.ID,
+		Name: spotifyResponse.Name,
+		Popularity: spotifyResponse.Popularity,
+		Genres: genreList,
+	}
+
+	// Create new record
+	// Otherwise update values when artist with this SpotifyID already exists
+	// Basically upsert
+	dbResult := env.db.Clauses(clause.OnConflict{
+		Columns: []clause.Column{{Name: "spotify_id"}},
+		UpdateAll: true,
+	}).Create(&artistProfile)
+
+	if dbResult.Error != nil {
+		slog.Error("[GOMUSIC] Failed to store response in local database", "Error", err)
+	}
 
     // Send back our response data
     c.JSON(http.StatusOK, spotifyResponse)
diff --git a/routes_test.go b/routes_test.go
index ee4de8f..41fd2cc 100644
--- a/routes_test.go
+++ b/routes_test.go
@@ -2,13 +2,17 @@ package main
 
 import (
 	"net/http"
+	"encoding/json"
 	"net/http/httptest"
 	"github.com/stretchr/testify/assert"
 	"testing"
+	"fmt"
 )
 
 func TestPingRoute(t *testing.T) {
-	router := setupRouter()
+	db := setupTestDatabase("testping")
+	env := &Env{db: db}
+	router := setupRouter(env, spotifyClientID, spotifyClientSecret)
 
 	w := httptest.NewRecorder()
 	req, _ := http.NewRequest("GET", "/ping", nil)
@@ -19,12 +23,33 @@ func TestPingRoute(t *testing.T) {
 }
 
 func TestGetArtistByIDRoute(t *testing.T) {
-	router := setupRouter()
+	db := setupTestDatabase("testgetartistbyid")
+	env := &Env{db: db}
+	router := setupRouter(env, spotifyClientID, spotifyClientSecret)
 
 	w := httptest.NewRecorder()
 	req, _ := http.NewRequest("GET", "/artists/0TnOYISbd1XYRBk9myaseg", nil)
 	router.ServeHTTP(w, req)
 
 	assert.Equal(t, 200, w.Code)
-	assert.Equal(t, `{"ID":"0TnOYISbd1XYRBk9myaseg","Name":"Pitbull","Popularity":83,"Genres":[]}`, w.Body.String())
+
+	// Dynamic data is hard to test so here we validate JSON response
+	// And we check known fields which are not likely to change
+	// We then check that the DB was updated correctly just to be sure
+	var spotifyResp SpotifyResponse
+	err := json.NewDecoder(w.Body).Decode(&spotifyResp)
+	if err != nil {
+		assert.Fail(t, fmt.Sprintf("Could not validate and parse JSON response into SpotifyResponse struct: %s", err.Error()))
+	}
+	assert.Equal(t, "0TnOYISbd1XYRBk9myaseg", spotifyResp.ID)
+	assert.Equal(t, "Pitbull", spotifyResp.Name)
+
+	var artist ArtistProfile
+	dbResult := env.db.First(&artist)
+	if dbResult.Error != nil {
+		assert.Fail(t, fmt.Sprintf("Failed to retrieve new info from test database: %s", err.Error()))
+	}
+	
+	assert.Equal(t, "Pitbull", artist.Name)
+	assert.Equal(t, "0TnOYISbd1XYRBk9myaseg", artist.SpotifyID)
 }
diff --git a/utils.go b/utils.go
new file mode 100644
index 0000000..14dfb22
--- /dev/null
+++ b/utils.go
@@ -0,0 +1,47 @@
+package main
+
+import (
+	"fmt"
+	"net/http"
+	"encoding/json"
+)
+
+type SpotifyResponse struct {
+       ID string
+       Name string
+       Popularity int
+       Genres []string
+}
+
+// Makes a request to spotify API to grab artist data
+// And parse the results into a properly typed struct
+func getSpotifyArtistData(artistID string, spotifyAuthToken string) (SpotifyResponse, error) {
+
+	artistEndpoint := fmt.Sprintf("https://api.spotify.com/v1/artists/%s", artistID)
+    req, err := http.NewRequest("GET", artistEndpoint, nil)
+    if err != nil {
+		return SpotifyResponse{}, fmt.Errorf("Failed to build HTTP request to spotify: %w", err)
+    }
+    req.Header.Add("Authorization", spotifyAuthToken)
+
+    // Send off request
+    resp, err := http.DefaultClient.Do(req)
+    if err != nil {
+		return SpotifyResponse{}, fmt.Errorf("Failed to get artist data from spotify API: %w", err)
+	} else if resp.StatusCode != 200 {
+		return SpotifyResponse{}, fmt.Errorf("Failed to get artist data from spotify API due to response status: %s", resp.Status)
+    }
+	
+	var spotifyResponse SpotifyResponse
+	err = json.NewDecoder(resp.Body).Decode(&spotifyResponse)
+    if err != nil {
+        return SpotifyResponse{}, fmt.Errorf("Failed to read response body data from spotify: %w", err)
+    }
+    
+    // Close this immediately since it's unused now
+    resp.Body.Close()
+
+	// After all the above checks we assume this response is populated
+	// If errors arise we can do extra validation here
+	return spotifyResponse, nil
+}