How to handle null value in golang?

huangapple go评论77阅读模式
英文:

How to handle null value in golang?

问题

用户模型

type UserExample struct {
    Id       primitive.ObjectID `json:"id,omitempty"`
    Name     string             `json:"name,omitempty"`
    Location string             `json:"location,omitempty"`
    Title    string             `json:"title,omitempty"`
}

更新用户

func UpdateUserExample() gin.HandlerFunc {
    return func(c *gin.Context) {
        ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
        userId := c.Param("userId")
        var user models.UserExample
        defer cancel()
        objId, _ := primitive.ObjectIDFromHex(userId)

        // 验证请求体
        if err := c.BindJSON(&user); err != nil {
            c.JSON(http.StatusBadRequest, responses.UserResponseExample{
                Status:  http.StatusBadRequest,
                Message: "Error",
                Data: map[string]interface{}{
                    "data": err.Error()},
            })
        }

        update := bson.M{
            "name":     user.Name,
            "location": user.Location,
            "title":    user.Title,
        }
        result, err := userCollectionExample.UpdateOne(ctx, bson.M{
            "id": objId,
        }, bson.M{
            "$set": update,
        })
        if err != nil {
            c.JSON(http.StatusInternalServerError, responses.UserResponseExample{
                Status:  http.StatusInternalServerError,
                Message: "Error",
                Data: map[string]interface{}{
                    "data": err.Error(),
                }})
            return
        }

        // 获取更新后的用户详细信息
        var updateUser models.UserExample
        if result.MatchedCount == 1 {
            err := userCollectionExample.FindOne(ctx, bson.M{
                "id": objId,
            }).Decode(&updateUser)
            if err != nil {
                c.JSON(http.StatusInternalServerError, responses.UserResponseExample{
                    Status:  http.StatusInternalServerError,
                    Message: "Error",
                    Data: map[string]interface{}{
                        "data": err.Error(),
                    }})
                return
            }
        }
        c.JSON(http.StatusOK, responses.UserResponseExample{
            Status:  http.StatusOK,
            Message: "Success",
            Data: map[string]interface{}{
                "data": updateUser,
            },
        })
    }
}

我尝试通过Postman更新数据,但如果值为null,将从集合中删除。

在这种情况下,我想要更新用户的标题,在更新之前保留所有已存在的数据。

Postman

{
    "title": "User One"
}

这将在集合中更改标题。但是,其他数据(姓名和位置)已经消失了。

"data": {
    "id": "63d2ac86aeb9d78d3d5daf21",
    "title": "User One"
}

那么,如何处理请求体中的null值?

我只想为此情况更改标题。

英文:

User model

type UserExample struct {
Id       primitive.ObjectID `json:"id,omitempty"`
Name     string             `json:"name,omitempty"`
Location string             `json:"location,omitempty"`
Title    string             `json:"title,omitempty"`
}

Update User

func UpdateUserExample() gin.HandlerFunc {
return func(c *gin.Context) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
userId := c.Param("userId")
var user models.UserExample
defer cancel()
objId, _ := primitive.ObjectIDFromHex(userId)
//Validate the request body
if err := c.BindJSON(&user); err != nil {
c.JSON(http.StatusBadRequest, responses.UserResponseExample{
Status:  http.StatusBadRequest,
Message: "Error",
Data: map[string]interface{}{
"data": err.Error()},
})
}
update := bson.M{
"name":     user.Name,
"location": user.Location,
"title":    user.Title,
}
result, err := userCollectionExample.UpdateOne(ctx, bson.M{
"id": objId,
}, bson.M{
"$set": update,
})
if err != nil {
c.JSON(http.StatusInternalServerError, responses.UserResponseExample{
Status:  http.StatusInternalServerError,
Message: "Error",
Data: map[string]interface{}{
"data": err.Error(),
}})
return
}
//Get Update UserExample Detail
var updateUser models.UserExample
if result.MatchedCount == 1 {
err := userCollectionExample.FindOne(ctx, bson.M{
"id": objId,
}).Decode(&updateUser)
if err != nil {
c.JSON(http.StatusInternalServerError, responses.UserResponseExample{
Status:  http.StatusInternalServerError,
Message: "Error",
Data: map[string]interface{}{
"data": err.Error(),
}})
return
}
}
c.JSON(http.StatusOK, responses.UserResponseExample{
Status:  http.StatusOK,
Message: "Success",
Data: map[string]interface{}{
"data": updateUser,
},
})
}
}

i have try update data via postman, but if value == null will be delete from collection

In this case, i want Update Title of the User, before update all data already exist

Postman

{
"title": "User One"
}

its working to change title in collection. but, for other data (name and location)has gone

"data": {
"id": "63d2ac86aeb9d78d3d5daf21",
"title": "User One",
}

so, how to handle null value from request body?

i just want change title for this case

答案1

得分: 2

通常,这样的部分更新使用以下结构来处理:

type UserUpdateRequest struct {
    Id       primitive.ObjectId `json:"id,omitempty"`
    Name     *string             `json:"name,omitempty"`
    Location *string             `json:"location,omitempty"`
    Title    *string             `json:"title,omitempty"`
}

注意指针的使用。这样,API 调用者可以发送非空值来更新字段。它还可以使用空字符串来将字段值设置为空。

然后,在数据库端,你需要创建一个更新语句:

updateFields := bson.M{}
if request.Name != nil {
   updateFields["name"] = *request.Name
}
if request.Location != nil {
   updateFields["location"] = *request.Location
}
// 等等。
update := bson.M{"$set": updateFields}

然后使用 update 来更新数据库记录。

英文:

Usually, such partial updates are handled using a structure that looks like this:

type UserUpdateRequest struct {
Id       primitive.ObjectId `json:"id,omitempty"`
Name     *string             `json:"name,omitempty"`
Location *string             `json:"location,omitempty"`
Title    *string             `json:"title,omitempty"`
}

Note the pointers. This way, the API caller can send non-nil values for the field it wants to update. It can also use an empty string to set the field values to empty.

Then on the database side, you have to create an update statement:

updateFields:=bson.M{}
if request.Name!=nil {
updateFields["name"]=*request.Name
}
if request.Location!=nil {
updateFields["location"]=*request.Location
}
// etc.
update:=bson.M{"$set":updateFields}

Then use the update to update the database record.

huangapple
  • 本文由 发表于 2023年1月27日 01:04:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75249414.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定