英文:
Getting "_id : 000000000" for every get request
问题
我最近开始使用GO并尝试创建一个API。这是一个基本的API,有几个get
和post
端点。每个端点都正常工作,但有一个例外。我在做与其他get端点相同的事情,但不明白为什么从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
是有效的。
英文:
I have recently started working with GO and tried to create an API. This was a basic API with few get
and post
endpoints. Every endpoint is working just fine but one. I am doing the same thing as in the other get endpoints but don't understand why am I getting the empty instance back from the mongoDB. And as far as I can guess, I think this is the problem due to data type.<br><br> This is my Post
struct.
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"`
}
This is the controller 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})
}
This is my main
package main
import (
"insta/controller"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
router.GET("/posts/:postId" , controller.GetPost)
router.Run()
}
I am getting this response.
PostId
is valid
答案1
得分: 1
问题是参数中的postId是string
类型,而mongodb中的postId是primitive.ObjectID
类型,它们不相同。
解决方案是在查询之前将其转换为MongoDB的ObjectID
类型。
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)
// 检查文档是否存在,如果不存在返回404错误
if errors.Is(err, mongo.ErrNoDocuments) {
c.JSON(http.StatusNotFound, gin.H{"message": "Post with the given id does not exist"})
return
}
// Mongodb网络或服务器错误
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"post": post})
}
英文:
The problem is the postId from the param is of type string
while the postId in mongodb is of type primitive.ObjectID
which are not the same.
The solution is to convert it to a MongoDB ObjectID
before querying.
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})
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论