douqi2804
2014-12-03 22:59
浏览 555

使用gin Golang框架配置mongo

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条回答 默认 最新

  • dongxian2863 2014-12-04 01:26
    已采纳

    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.

    已采纳该答案
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题