创建一个函数,该函数返回带有Golang和MGO的mongo集合

I'm new to GOLANG - I would like to reduce the complexity of the handlers in my GO API. I'm coming from a Node.js background!

At the moment a route handler looks like this:

func getCards(c web.C, w http.ResponseWriter, r *http.Request) {

    session := *MongoConnection().CreateSession()
    defer session.Close()

    collection := session.DB(db).C(cardsCollection)

    result := []Card{}

    err := collection.Find(bson.M{}).All(&result)
    if err != nil {
        panic(err)
    }

    w.Header().Set("Content-Type", "application/json")
    encoder := json.NewEncoder(w)
    encoder.Encode(result)
}

What I would like to do is return a collection for use without having to do this part:

session := *MongoConnection().CreateSession()
defer session.Close()

collection := session.DB(db).C(cardsCollection)

Instead I would like to do something like

collection := Card.Collection()

And have it create the session etc, Is this possible?

Why don't you have the session created in your main function, and pass it to the packages that need it. This is obviously missing a ton of stuff but the general idea would be

package main
//imports
func main() {
    session := *MongoConnection().CreateSession()
    defer session.Close()
    Card.SetSession(session)
    //other stuff
    log.Fatal(http.ListenAndServe(":80", nil))
}

Then in Card

package Card

var session *mgo.Session

func SetSession(s *mgo.Session) {
    session = s
}

func (c *Card) Collection() *mgo.Collection {
    return session.DB(db).C(cardsCollection)
}

What you are describing is a factory pattern. But there are caveats to deal with. Defer is local to scope it is called. So in case you would put the defer into a factory method, the session would be closed basically when it is returned.

Simply defining just one session und reuse it all over the place is pretty much the same as using a single SQL database connection and not a pool - it scales horribly.

Here is what I tend to do: I have my collections as global, and do the following at the beginning of my method

// Create a func-local session
myCollection := globalCollection.With( globalCollection.Database.Session.Copy() )
// Close it on exiting the scope
defer myCollection.Database.Session.Close()

Of course, you could externalize the first line into a factory, but that would not really declutter the code or make it more readable.