Reputation: 109
When updating a resource via REST, should one include in the body just the values to update, or the whole object (current values and values to update)?
If a User object looks like this
User (id, name, age, sex)
and I want to update only his name and age, should my request look like this:
PUT /users/1
{"name":"john","age":18}
or like this:
PUT /users/1
{"name":"john","age":18, "sex":"m"}
And what should that look like on the server side?
@RequestMapping(value = "/{userId}", method = PUT, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> updateUser(@PathVariable final int userId, @RequestBody User u){
//fetch user by ID
user.setName(u.getName())
user.setAge(u.getAge())
user.setSex(u.getSex()) //this will be empty?
return new ResponseEntity<String>(gson.toJson(user), HttpStatus.OK);
}
Or alternatively I could find out which variables were not included in the request body and do something like this
if(u.getName()!=null){
user.setName(u.getName())
}
if(u.getAge()!=null){
user.setAge(u.getAge())
}
if(u.getSex()!=null){
user.setSex(u.getSex())
}
Is there a right/wrong way to achieve this, or is it a case of just doing what's easiest?
Upvotes: 1
Views: 3143
Reputation: 61
PUT
requests must be idempotent and should provide as its payload a complete representation of the entity it is replacing. (https://www.rfc-editor.org/rfc/rfc7231#section-4.3.4)
The PUT method requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload.
A partial JSON object PUT
request would be a PATCH
with Content-Type: application/merge-patch+json
(https://www.rfc-editor.org/rfc/rfc7396)
Things to think about. You might have multiple clients updating an entity at the same time, using a PUT could end up overwriting changes other clients have made.
In that case you might want to set a pre-condition
to check if the object was updated between the time that the requesting client fetched the entity, made changes and submitted the PUT/PATCH request. For example the pre-condition could be a last updated timestamp, hash (Etag) or a version number; Or you could use a "last write wins" approach which is common in eventually consistent systems. It all depends on your system and the situation.
On the server side, if you support partial updates then as you have provided in your example, you would identify the set of properties included in the request and only set the specific ones that were provided.
Upvotes: 5