1
votes

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 Answers

1
votes

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.