如何使用Gin web框架将参数传递给Golang中的路由器处理程序?
我正在使用Gin,用Golang构建一个简单的restfuljsonapi 路线的设置如下所示:如何使用Gin web框架将参数传递给Golang中的路由器处理程序?,go,go-gin,Go,Go Gin,我正在使用Gin,用Golang构建一个简单的restfuljsonapi 路线的设置如下所示: func testRouteHandler(c *gin.Context) { // do smth } func main() { router := gin.Default() router.GET("/test", testRouteHandler) router.Run(":8080") } 我的问题是如何将参数传递给testRouteHandler函数?
func testRouteHandler(c *gin.Context) {
// do smth
}
func main() {
router := gin.Default()
router.GET("/test", testRouteHandler)
router.Run(":8080")
}
我的问题是如何将参数传递给testRouteHandler函数?例如,公共数据库连接可能是希望在路由之间重用的连接
将其放入全局变量中的最佳方法是什么?或者Go中是否有某种方法将额外的变量传递给testRouteHandler函数?Go中是否有函数的可选参数
另外,我刚刚开始学习围棋,所以可能有一些明显的东西我没有:)使用我在评论上发布的链接,我创建了一个简单的例子
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。但我相信这是一个开始。
希望能有所帮助。我会避免将“应用程序范围”依赖项(例如数据库连接池)塞进请求上下文中。您的两个“最简单”选项是:
*sql.DB
是线程安全的好的,我给你举了一个简单的例子。它应该会起作用。您可以根据需要扩展它
func main() {
router := gin.Default()
router.GET("/test/:id/:name", testRouteHandler)
router.Run(":8080")
}
func testRouteHandler(c *gin.Context) {
id := c.Params.ByName("id")
name := c.Params.ByName("name")
}
现在,您必须按如下方式调用处理程序
晚会迟到了,到目前为止,这是我的建议。将方法装入包含私有/公共变量的对象中:
package main
import (
"log"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
_ "github.com/mattn/go-sqlite3"
)
type HandlerA struct {
Db gorm.DB
}
func (this *HandlerA) Get(c *gin.Context) {
log.Info("[%#f]", this.Db)
// do your thing here...
}
func main() {
r := gin.New()
// Init, should be separate, but it's ok for this sample:
db, err := gorm.Open("sqlite3", "./example.db")
if err != nil {
log.Fatal(err)
}
Obj := new(HandlerA)
Obj.Db = db // Or init inside Object
r := gin.New()
Group := r.Group("api/v1/")
{
Group.GET("/storage", Obj.Get)
}
r.Run(":8080")
}
我喜欢wildneuro的示例,但会使用一行程序来设置处理程序
package main
import (
"log"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
_ "github.com/mattn/go-sqlite3"
)
type HandlerA struct {
Db gorm.DB
}
func (this *HandlerA) Get(c *gin.Context) {
log.Info("[%#f]", this.Db)
// do your thing here...
}
func main() {
r := gin.New()
// Init, should be separate, but it's ok for this sample:
db, err := gorm.Open("sqlite3", "./example.db")
if err != nil {
log.Fatal(err)
}
r := gin.New()
Group := r.Group("api/v1/")
{
Group.GET("/storage", (&HandlerA{Db: db}).Get)
}
r.Run(":8080")
}
让我试着详细解释一下,这样你就不会感到困惑了
/books
,控制器为BooksController
BooksController
将尝试从数据库中获取书籍并返回响应BooksController
中有一个处理程序,以便访问数据库
我会这样做。假设您使用的是dynamoDB,aws sdk提供了*dynamoDB.dynamoDB
。根据您的数据库,更改此变量
initDatabaseConnection
,它将处理程序返回给db,如下所示db:=initDatabaseConnection()
->返回*dynamodb.dynamodb
db
设置为结构变量serviceConnection
struct receiver创建一个控制器方法正如您在这里看到的,您可以访问所有的
serviceConnection
struct变量,并且可以在控制器中使用它们。我认为您正在寻找HTTP中间件这是一个很好的起点,正如@MIkCode所说,中间件是一个不错的选择。。。看看杜松子酒的定制中间产品。这应该是推荐的答案。不幸的是,在使用Use
和Group
()等方法时,我在让这个闭包模式与Gin框架很好地配合时遇到了多个问题,我建议使用Set
和Get
方法,直到Gin设计得更好。我很少提倡更糟糕的设计,但最好在方法上保持一致并利用框架。很好的模式,但是Gin还没有。如何在chi框架中实现同样的“将db连接添加到上下文”呢?不幸的是,这是最好的答案。这并不理想,因为Set
和Get
创建了一个依赖项,其中闭包模式可以简单地将参数从中间件传递到封闭的路由。然而,Gin并不自然地使用闭包模式,因此一些方法,如使用
和组
变得复杂。
package main
import (
"log"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
_ "github.com/mattn/go-sqlite3"
)
type HandlerA struct {
Db gorm.DB
}
func (this *HandlerA) Get(c *gin.Context) {
log.Info("[%#f]", this.Db)
// do your thing here...
}
func main() {
r := gin.New()
// Init, should be separate, but it's ok for this sample:
db, err := gorm.Open("sqlite3", "./example.db")
if err != nil {
log.Fatal(err)
}
r := gin.New()
Group := r.Group("api/v1/")
{
Group.GET("/storage", (&HandlerA{Db: db}).Get)
}
r.Run(":8080")
}
type serviceConnection struct {
db *dynamoDB.DynamoDB
// You can have all services declared here
// which you want to use it in your controller
}
conn := new(serviceConnection)
conn.db = db
r := gin.Default()
r.GET("/books", conn.BooksController)
func (conn *serviceConnection) BooksController(c *gin.Context) {
books := getBooks(conn.db)
}