I just started checking Go, and I'm looking to reimplement the API server written in node with it.
I ran into an obstacle trying to use dependency injection to pass the database context as gin middleware. So far I have installed this as:
main.go:
package main import ( "fmt" "runtime" "log" "github.com/gin-gonic/gin" "votesforschools.com/api/public" "votesforschools.com/api/models" ) type DB struct { models.DataStore } func main() { ConfigRuntime() ConfigServer() } func Database(connectionString string) gin.HandlerFunc { dbInstance, err := models.NewDB(connectionString) if err != nil { log.Panic(err) } db := &DB{dbInstance} return func(c *gin.Context) { c.Set("DB", db) c.Next() } } func ConfigRuntime() { nuCPU := runtime.NumCPU() runtime.GOMAXPROCS(nuCPU) fmt.Printf("Running with %d CPUs\n", nuCPU) } func ConfigServer() { gin.SetMode(gin.ReleaseMode) router := gin.New() router.Use(Database("<connectionstring>")) router.GET("/public/current-vote-pack", public.GetCurrentVotePack) router.Run(":1000") }
models / db.go
package models import ( "database/sql" _ "github.com/go-sql-driver/mysql" ) type DataStore interface { GetVotePack(id string) (*VotePack, error) } type DB struct { *sql.DB } func NewDB(dataSource string) (*DB, error) { db, err := sql.Open("mysql", dataSource) if err != nil { return nil, err } if err = db.Ping(); err != nil { return nil, err } return &DB{db}, nil }
models / votepack.go
package models import ( "time" "database/sql" ) type VotePack struct { id string question string description string startDate time.Time endDate time.Time thankYou string curriculum []string } func (db *DB) GetVotePack(id string) (*VotePack, error) { var votePack *VotePack err := db.QueryRow( "SELECT id, question, description, start_date AS startDate, end_date AS endDate, thank_you AS thankYou, curriculum WHERE id = ?", id).Scan( &votePack.id, &votePack.question, &votePack.description, &votePack.startDate, &votePack.endDate, &votePack.thankYou, &votePack.curriculum) switch { case err == sql.ErrNoRows: return nil, err case err != nil: return nil, err default: return votePack, nil } }
So, with all of the above, I want to pass models.DataSource as middleware so that it can be obtained as follows:
open / public.go
package public import ( "github.com/gin-gonic/gin" ) func GetCurrentVotePack(context *gin.Context) { db := context.Keys["DB"] votePack, err := db.GetVotePack("c5039ecd-e774-4c19-a2b9-600c2134784d") if err != nil{ context.String(404, "Votepack Not Found") } context.JSON(200, votePack) }
However, I get public\public.go:10: db.GetVotePack undefined (type interface {} is interface with no methods)
When I check in the debugger (using Webstorm with the plugin), db is just an empty object. I try to be good and avoid using global variables