vendredi 3 juillet 2020

Cannot get response from golang gin-gonic with mongoDB (mongo-go-driver)

wrote a simple app with golang gin-gonic framework and mongoDB (on MongoDB Atlas). I tried to get a document and responsed successfully on server side.

However, Postman could not get the response and raised an error: socket hang up. And curl also failed and got "the underlying connection was closed: the connection was closed unexpectedly", while the server responsed twice.

But I also tested both Postman and curl with "/ping" router and they could get response "pong" normally. Thus I believe this problem is related to mongoDB (mongo-go-driver).

Router

[GIN-debug] GET    /ping                     --> scopelens-server/routers.InitRouters.func1 (4 handlers)
[GIN-debug] GET    /api/user/username/:username --> scopelens-server/api/v1.GetUserByName (4 handlers)

API

func GetUserByName(c *gin.Context) {
    username := c.Param("username")
    user, err := models.Db.GetUserByUsername(username)
    if err != nil {
        panic(err)
    } else {
        log.Println(user) // &{ObjectID("5efeda1a8a74c5c4071dc4e1") admin admin@admin.com 111111}
        c.JSON(http.StatusOK, gin.H{
            "code": 0,
            "msg":  "ok",
            "data": user,
        })
    }
}

User Model

// The User holds
type User struct {
    ID       primitive.ObjectID `bson:"_id" json:"id"`
    UserName string             `bson:"username" json:"username"`
    Email    string             `bson:"email" json:"email"`
    Password string             `bson:"password" json:"password"`
}

// GetUserByName returns the user by the given name or nil.
func (d *DBDriver) GetUserByUsername(username string) (*User, error) {
    var user *User
    err := d.DB.Collection("users").
        FindOne(context.Background(), bson.D).
        Decode(&user)
    if err != nil {
        return nil, err
    }
    return user, nil
}

Database

// Database instance
var Db *DBDriver

// DBDriver is a wrapper for the mongo-go-driver.
type DBDriver struct {
    DB      *mongo.Database
    Client  *mongo.Client
    Context context.Context
}

// Close closes the mongo-go-driver connection.
func (d *DBDriver) Close() {
    d.Client.Disconnect(d.Context)
}

func InitDB() (*DBDriver, error) {
    // Define a timeout duration
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()

    // Configure our client to use the correct URI, but we're not yet connecting to it.
    client, err := mongo.NewClient(options.Client().ApplyURI(config.Database.AtlasURI))
    if err != nil {
        return nil, err
    }

    // Try to connect using the defined timeout duration
    if err := client.Connect(ctx); err != nil {
        return nil, err
    }

    // Ping the cluster to ensure we're already connected
    ctxPing, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    if err := client.Ping(ctxPing, readpref.Primary()); err != nil {
        return nil, err
    }

    db := client.Database(config.Database.DBName)
    return &DBDriver{DB: db, Client: client, Context: ctx}, nil
}

Thanks!




Aucun commentaire:

Enregistrer un commentaire