为每个获取请求获取“_id:000000000”

Getting "_id : 000000000" for every get request

我最近开始使用 GO 并尝试创建一个 API。这是一个基本的 API,只有几个 getpost 端点。除了一个端点之外,每个端点都工作得很好。我正在做与其他获取端点相同的事情,但不明白为什么我要从 mongoDB 返回空实例。据我猜测,我认为这是数据类型的问题。

这是我的 Post 结构。

package models

import (
    "time"

    "go.mongodb.org/mongo-driver/bson/primitive"
)

type Posts struct {
    Id       primitive.ObjectID `json:"id" bson:"_id" validate:"nil=false"`
    Caption  string             `json:"caption" bson:"caption"`
    ImageUrl string             `json:"imageUrl" bson:"imageUrl" validate:"nil=false"`
    Author   string             `json:"author" bson:"author" validate:"nil:false"`
    Time     time.Time          `json:"time" bson:"time"`
}

这是控制器getPost

package controller

import (
    "insta/models"
    "log"
    "net/http"

    "github.com/gin-gonic/gin"
    "go.mongodb.org/mongo-driver/bson"
    // "go.mongodb.org/mongo-driver/bson/primitive"
)

func GetPost(c *gin.Context) {
    var post models.Posts
    postId := c.Param("postId")
    client, ctx, cancel := getConnection()
    defer cancel()
    defer client.Disconnect(ctx)
    err := client.Database("instagram").Collection("posts").FindOne(ctx, bson.M{"_id": postId}).Decode(&post)
    if err != nil {
        log.Printf("Couldn't get the Post")
    }
    c.JSON(http.StatusOK, gin.H{"post": post})
}

这是我的main

package main

import (
    "insta/controller"

    "github.com/gin-gonic/gin"
)

func main() {
    router := gin.Default()
    router.GET("/posts/:postId" , controller.GetPost)
    router.Run()
}

我收到了这个回复。

PostId有效

问题是参数中的 postId 是 string 类型,而 mongodb 中的 postId 是 primitive.ObjectID 类型,两者不相同。

解决方法是在查询之前将其转换为MongoDBObjectID

func GetPost(c *gin.Context) {
    var post models.Posts
    postId := c.Param("postId")
    postObjectId, err := primitive.ObjectIDFromHex(postId)
    if err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"message": "PostID is not a valid ObjectID"})
        return
    }

    client, ctx, cancel := getConnection()
    defer cancel()
    defer client.Disconnect(ctx)

    err = client.Database("instagram").Collection("posts").FindOne(ctx, bson.M{"_id": postObjectId}).Decode(&post)
    // Check if document exists return 404 error
    if errors.Is(err, mongo.ErrNoDocuments) {
        c.JSON(http.StatusNotFound, gin.H{"message": "Post with the given id does not exist"})
        return
    }

    // Mongodb network or server error
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()})
        return
    }

    c.JSON(http.StatusOK, gin.H{"post": post})
}