Jason
Jason

Reputation: 555

How to pass type into an http handler

I'm attempting to separate my http go code into "controllers" by creating a new package for them, but can't figure out how to pass a db type into the handler. I want to be able to pass in the Db type that I create in main.go into my Index handler in index.go. If this is the wrong way to solve this, let me know a better way (I'm learning as I go and would like to keep it simple for now). My code so far:

main.go:

package main

import (

    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    "github.com/gorilla/mux"
    "log"
    "mvc3/app/c"
    "net/http"
)

var Db *sql.DB

func main() {

    fmt.Println("Starting up!")

    var err error
    Db, err = sql.Open("mysql", "root@/dev?charset=utf8")
    if err != nil {
        log.Fatalf("Error on initializing database connection: %s", err.Error())
    }

    Db.SetMaxIdleConns(100)

    err = Db.Ping()
    if err != nil {
        log.Fatalf("Error on opening database connection: %s", err.Error())
     }

     r := mux.NewRouter()
     r.HandleFunc("/", c.Index)

    http.Handle("/", r)
    http.ListenAndServe(":8080", nil)
}

/app/c/index.go:

package c

import (
    "fmt"
    "net/http"
)

func Index(w http.ResponseWriter, r *http.Request) {

    fmt.Fprintf(w, "Hello world!")

}

Thanks!

Upvotes: 2

Views: 1924

Answers (1)

Jeremy Wall
Jeremy Wall

Reputation: 25245

use a closure.

in app/c change Index to:

func Index(db *sql.DB) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // do stuff with db here
        fmt.Fprintf(w, "Hello world!")
    }
}

then in your main function use it like so: r.HandleFunc("/", c.Index(db))

The Index function returns an anonymous function that fits the the HandleFunc type and also closes over the value of the db that was passed in giving your handler access to that variable.

Upvotes: 11

Related Questions