Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass arguments to router handlers in Golang using Gin web framework?

Tags:

go

go-gin

I'm using Gin, https://gin-gonic.github.io/gin/, to build a simple RESTful JSON API with Golang.

The routes are setup with something like this:

func testRouteHandler(c *gin.Context) {     // do smth }  func main() {     router := gin.Default()     router.GET("/test", testRouteHandler)     router.Run(":8080") } 

My question is how can I pass down an argument to the testRouteHandler function? For example a common database connection could be something that one wants to reuse among routes.

Is the best way to have this in a global variable? Or is there some way in Go to pass along an extra variable to the testRouteHandler function? Are there optional arguments for functions in Go?

PS. I'm just getting started in learning Go, so could be something obvious that I'm missing :)

like image 713
Niklas9 Avatar asked Dec 02 '15 15:12

Niklas9


People also ask

What is gin Handlerfunc?

Gin is a web framework written in Go (Golang). It features a martini-like API with much better performance, up to 40 times faster thanks to httprouter. If you need performance and good productivity, you will love Gin.

What is gin Default ()?

gin. Default() creates a Gin router with default middleware: logger and recovery middleware. Next, we make a handler using router. GET(path, handle) , where path is the relative path,​ and handle is the handler function that takes *gin. Context as an argument.

What is C * gin context?

Returns the specified key from a POST urlencoded form or multipart form when it exists, otherwise it returns the specified defaultValue string. func SomeHandler(c *gin. Context) { key := c. PostForm("key", "default value")


1 Answers

I would avoid stuffing 'application scoped' dependencies (e.g. a DB connection pool) into a request context. Your two 'easiest' options are:

  1. Make it a global. This is OK for smaller projects, and *sql.DB is thread-safe.
  2. Pass it explicitly in a closure so that the return type satisfies gin.HandlerFunc

e.g.

// SomeHandler returns a `func(*gin.Context)` to satisfy Gin's router methods // db could turn into an 'Env' struct that encapsulates all of your // app dependencies - e.g. DB, logger, env vars, etc. func SomeHandler(db *sql.DB) gin.HandlerFunc {     fn := func(c *gin.Context) {         // Your handler code goes in here - e.g.         rows, err := db.Query(...)          c.String(200, results)     }      return gin.HandlerFunc(fn) }  func main() {     db, err := sql.Open(...)     // handle the error      router := gin.Default()     router.GET("/test", SomeHandler(db))     router.Run(":8080") } 
like image 199
elithrar Avatar answered Sep 23 '22 17:09

elithrar