Home > Back-end >  Getting "_id : 000000000" for every get request
Getting "_id : 000000000" for every get request

Time:10-11

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.

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.

enter image description here

PostId is valid

enter image description here

CodePudding user response:

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})
}
  • Related