I'm building a golang backend using gorilla/mux and gocql. My objective is to create a session to a remote cassandra and share the very same session to a serie of handlers.
I came out with this implementation:
server.go:
package main
import (
"fmt"
"net/http"
"os"
"github.com/andream16/price-probe-go/api/item/rest"
"github.com/andream16/price-probe-go/cassandra"
"github.com/gorilla/mux"
)
func main() {
fmt.Println("Initializing Cassandra connection . . .")
s, err := cassandra.InitCassandraClient()
if err != nil {
fmt.Println("Unable to set up Cassandra client!")
os.Exit(1)
}
fmt.Println("Successfully initialized Cassandra connection . . .")
fmt.Println("Starting server . . .")
router := mux.NewRouter()
router.HandleFunc("/item", itemrest.ItemHandler(&s))
. . .
}
I create a new HandleFunc
for each route and pass it &s
.
And each handler is like:
func ItemHandler(session *gocql.Session) func(w http.ResponseWriter, r *http.Request) { }
Is there a more elegant way to achieve this?
1 Answer 1
Yes, there definitely is a better way to do this. The easiest way would be to use reciever functions (aka methods) as handler functions. Rather than returning a handler from the ItemHandler
func (bad name BTW), simple declare a handler directly.
Here's an example of how you could acchieve this:
type MyServer struct {
cql *gocql.Session
}
func (s *MyServer) ItemHandler(w http.ResponseWriter, r *http.Request) {
// use s.cql here
}
func New(cql *gocql.Session) (*MyServer, error) {
s := &MyServer{
cql: cql,
}
// more stuff here
return s, nil
}
Then, in your main package, simply write this:
s, err := cassandra.InitCassandraClient()
if err != nil {
fmt.Println("Unable to set up Cassandra client!")
os.Exit(1)
}
// assume package name server
srv, _ := server.New(&s)
// now ItemHandler with srv as receiver is the handler
router.HandleFunc("/item", srv.ItemHandler)