为每个获取请求获取“_id:000000000”
Getting "_id : 000000000" for every get request
我最近开始使用 GO 并尝试创建一个 API。这是一个基本的 API,只有几个 get
和 post
端点。除了一个端点之外,每个端点都工作得很好。我正在做与其他获取端点相同的事情,但不明白为什么我要从 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})
}
我最近开始使用 GO 并尝试创建一个 API。这是一个基本的 API,只有几个 get
和 post
端点。除了一个端点之外,每个端点都工作得很好。我正在做与其他获取端点相同的事情,但不明白为什么我要从 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})
}