我正在使用Gin,https: //gin-gonic.github.io/gin/,用Golang构建一个简单的RESTful JSON API.
路线设置如下:
func testRouteHandler(c *gin.Context) { // do smth } func main() { router := gin.Default() router.GET("/test", testRouteHandler) router.Run(":8080") }
我的问题是如何将参数传递给testRouteHandler函数?例如,公共数据库连接可能是想要在路由之间重用的东西.
在全局变量中使用它的最佳方法是什么?或者Go中有一些方法可以将额外的变量传递给testRouteHandler函数吗?Go中的函数是否有可选参数?
PS.我刚刚开始学习Go,所以可能是一些我很想念的东西:)
我会避免将"应用程序作用域"依赖项(例如数据库连接池)填充到请求上下文中.你最简单的两个选择是:
让它成为全球性的.对于较小的项目,这是可以的,并且*sql.DB
是线程安全的.
在闭包中显式传递它,以便返回类型满足 gin.HandlerFunc
例如
// 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") }
使用我在评论上发布的链接,我创建了一个简单的例子.
package main import ( "log" "github.com/gin-gonic/gin" "github.com/jinzhu/gorm" _ "github.com/mattn/go-sqlite3" ) // ApiMiddleware will add the db connection to the context func ApiMiddleware(db gorm.DB) gin.HandlerFunc { return func(c *gin.Context) { c.Set("databaseConn", db) c.Next() } } func main() { r := gin.New() // In this example, I'll open the db connection here... // In your code you would probably do it somewhere else db, err := gorm.Open("sqlite3", "./example.db") if err != nil { log.Fatal(err) } r.Use(ApiMiddleware(db)) r.GET("/api", func(c *gin.Context) { // Don't forget type assertion when getting the connection from context. dbConn, ok := c.MustGet("databaseConn").(gorm.DB) if !ok { // handle error here... } // do your thing here... }) r.Run(":8080") }
这只是一个简单的POC.但我相信这是一个开始.希望能帮助到你.