title: Go and Gin: Passing around struct for database context?
body: <p>I've just started trying out Go, and I'm looking to re-implement an API server written in node with it.</p>
  
  <p>I've hit a hurdle with trying to use dependency injection to pass around a database context as a gin middleware.  So far I've set it up as this:</p>
  
  <p>main.go:</p>
  
  <pre><code>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 := &amp;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("&lt;connectionstring&gt;"))
          router.GET("/public/current-vote-pack", public.GetCurrentVotePack)
          router.Run(":1000")
  }
  </code></pre>
  
  <p>models/db.go</p>
  
  <pre><code>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 &amp;DB{db}, nil
  }
  </code></pre>
  
  <p>models/votepack.go</p>
  
  <pre><code>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(
                  &amp;votePack.id, &amp;votePack.question, &amp;votePack.description, &amp;votePack.startDate, &amp;votePack.endDate, &amp;votePack.thankYou, &amp;votePack.curriculum)
  
          switch {
          case err == sql.ErrNoRows:
                  return nil, err
          case err != nil:
                  return nil, err
           default:
                  return votePack, nil
          }
  }
  </code></pre>
  
  <p>So with all of the above, I want to pass the models.DataSource around as a middleware so it can be accessed like this:</p>
  
  <p>public/public.go</p>
  
  <pre><code>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)
  }
  </code></pre>
  
  <p>However I get <code>public\public.go:10: db.GetVotePack undefined (type interface {} is interface with no methods)</code></p>
  
  <p>When I inspect in the debugger (using Webstorm with plugin) the db is just an empty object.  I'm trying to be good and avoid global variable use</p>