douqi2804 2014-12-03 22:59
浏览 630
已采纳

使用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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!