So i have built a simple REST API with Gin, that can make POST, and GET requests to add user objects and retrieve them. The users are of type struct, and and are stored in a slice. This just runs in memory, and is therefore not connected to a database.
I wanted to create a new function, that can update an existing user with a PATCH request, but what i made doesn't seem to work correctly:
func updateUser(c *gin.Context) {
id := c.Param("id")
var updatedUser user
if err := c.BindJSON(&updatedUser); err != nil {
return
}
updatedId := updatedUser.ID
updatedFirstName := updatedUser.FirstName
updatedLastName := updatedUser.LastName
updatedEmail := updatedUser.Email
for _, user := range users {
if updatedUser.ID == id {
user.ID = updatedId
user.FirstName = updatedFirstName
user.LastName = updatedLastName
user.Email = updatedEmail
users = append(users, updatedUser)
c.JSON(http.StatusCreated, gin.H{"success": "user updated"})
return
}
}
c.JSON(http.StatusNotFound, gin.H{"error": "user not found"})
}
This just creates a new user and appends it to the end of my slice, instead of updating the user with id specified in the URL with the request. How can i make this function work, to update the values of my user object, while still keeping the same order in the slice?
CodePudding user response:
Your code creates a copy of the user, changes it, and appends it to the end of the slice. If you want to amend a user then you can do something like this:
for i := range users {
if users[i].ID == id {
users[i].ID = updatedId // Are you sure this is what you want!
users[i].FirstName = updatedFirstName
users[i].LastName = updatedLastName
users[i].Email = updatedEmail
c.JSON(http.StatusOK, gin.H{"success": "user updated"})
return
}
c.JSON(http.StatusNotFound, gin.H{"error": "user not found"})
}
A few notes on this:
- Assumes that the slice will only ever contain one user with that ID.
- Allows the logged on user (I assume that is what
c.Param("id")
is) to update their own ID. This is not something you would generally want to do (I could just change my user ID to the ID of an admin user and, potentially, gain admin access). - A patch request "applies partial modifications to a resource" so generally you would only update the attributes that are provided (rather than replacing everything - that would be a PUT).
- Currently this code is not threadsafe; multiple users might make simultaneous patch requests (potential data races)