英文:
Configuring mongo with gin golang framework
问题
我正在尝试在我的Go应用程序中配置Mongo数据库。我正在使用Gin框架,并且使用mgo V2驱动程序来连接Mongo数据库。我想将Mongo连接作为中间件使用。以下是我的代码:
func Run(cfg common.Config) error {
doWorkResource := &DoWorkResource{db: dbmap}
r := gin.New()
r.Use(middleware.DB())
r.POST("/register", doWorkResource.Register)
r.POST("/login", doWorkResource.Login)
r.Run(cfg.SvcHost)
return nil
}
func DB() gin.HandlerFunc {
session, err := mgo.Dial("localhost:27017")
if err != nil {
panic(err)
}
defer session.Close()
return func(c *gin.Context) {
s := session.Clone()
db := s.DB("testing").C("testData")
err = db.Insert(&Person{"Ale", "+55 53 8116 9639"}, &Person{"Cla", "+55 53 8402 8510"})
if err != nil {
log.Fatal(err)
}
c.Next()
}
}
type Person struct {
Name string
Phone string
}
如果我直接从主函数运行代码,插入操作是可以执行的,但是如果从DB()函数运行,插入操作就不会执行。实际上,我在DB()函数的返回语句中记录了日志,但是其中的任何内容都没有被执行。我有一种感觉,我需要将其作为参数调用我的某个端点,但是当我这样做时,我得到了以下错误信息:
cannot use middleware.DB (type func() gin.HandlerFunc) as type gin.HandlerFunc in argument to r.RouterGroup.POST
请帮我看看问题出在哪里。
英文:
I'm trying to configure mongo in my Go app. I'm using the Gin framework. I'm also using the mgo V2 driver for mongo. I want to connect to mongo as a middlware. Here's what I got:
func Run(cfg common.Config) error {
doWorkResource := &DoWorkResource{db: dbmap}
r := gin.New()
r.Use(middleware.DB())
r.POST("/register", doWorkResource.Register)
r.POST("/login", doWorkResource.Login)
r.Run(cfg.SvcHost)
return nil
}
This is the DB function:
func DB() gin.HandlerFunc {
session, err := mgo.Dial("localhost:27017")
if err != nil {
panic(err)
}
defer session.Close()
return func(c *gin.Context) {
s := session.Clone()
db := s.DB("testing").C("testData")
err = db.Insert(&Person{"Ale", "+55 53 8116 9639"},
&Person{"Cla", "+55 53 8402 8510"})
if err != nil {
log.Fatal(err)
}
c.Next()
}
}
type Person struct {
Name string
Phone string
}
The insertion is executed if I run it directly from the main function, but not if it's run from the DB() function. In fact, I logged from within the return statement in the DB() function and nothing in there is being executed. I have a feeling I need to call it as an argument to one of my endpoints, but when I do that I get
cannot use middleware.DB (type func() gin.HandlerFunc) as type gin.HandlerFunc in argument to r.RouterGroup.POST
答案1
得分: 1
看起来你的问题就在这里:
defer session.Close()
当你注册中间件时,实际上并不是每次调用都会调用该中间件,而是定义了每次调用时要执行的操作。首先,你运行一组初始命令。这部分代码如下:
session, err := mgo.Dial("localhost:27017")
if err != nil {
panic(err)
}
defer session.Close()
然后,你返回一组指令,以便在每次访问其中一个端点时运行。这部分代码如下:
s := session.Clone()
db := s.DB("testing").C("testData")
err = db.Insert(&Person{"Ale", "+55 53 8116 9639"},
&Person{"Cla", "+55 53 8402 8510"})
if err != nil {
log.Fatal(err)
}
c.Next()
当从中间件初始化程序返回时,它会激活 defer
语句。然后,当第一个调用进来并尝试运行你以 HandlerFunc
形式返回的指令时,它会失败,因为它尝试使用的会话已经关闭了。
英文:
Looks like your problem is right here:
defer session.Close()
What you're really doing when you register the middleware is not call that middleware every time a call comes in, but defining what to do every time a call comes in. First you run a initial set of commands. That would be this part:
session, err := mgo.Dial("localhost:27017")
if err != nil {
panic(err)
}
defer session.Close()
And then you return a set of instructions to run every time one of your endpoints gets hit, that would be this part:
s := session.Clone()
db := s.DB("testing").C("testData")
err = db.Insert(&Person{"Ale", "+55 53 8116 9639"},
&Person{"Cla", "+55 53 8402 8510"})
if err != nil {
log.Fatal(err)
}
c.Next()
And when you return from the middleware initializer, it activates the defer
statement. Then when the first call comes in and tries to run the instructions you returned in the form of a HandlerFunc
it fails because the session it is trying to use has already been closed.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论