给定一个控制器,它将为User
创建/更新/删除/查询:
Get /users query the list
Post /users add a new user
Get /users/1 query a single record
Delete /users/1 delete a single record
Put /users/1 update a single record
请注意上一个Put
操作方法/users/1
,这意味着应使用请求中的数据更新标识1
的用户。
但是假设具有标识1的用户具有以下属性(部分):
{username:uname,location:sg}
现在提出以下要求:
PUT /user/1
username=hg
PUT /user/1
username=hg&location=
我们应该将username
设置为hg
,但我们如何处理location
?它应该设置为null还是保留在数据库中?
通常我们可以在控制器中使用类似spring mvc的数据绑定:
@RequestMapping(value="/{userId}",method="PUT")
public String update(@PathVariable String userId, User user){
//merge the model, suppose the `user` contains all the properties of the user
user = entityManager.merge(user);
entityManager.persist(user);
return "user/show"
}
在这种情况下,一旦执行了两个示例请求,该位置将在数据库中设置为null,这可能与客户想要的一样。
通常,我们应该使用Patch
来更新资源的部分属性,但并非所有框架都支持该方法。
而且,甚至支持Patch
方法也是如此:
@RequestMapping(value="/{userId}",method="PATCH")
public String updatePartial(@PathVariable String userId, User user){
//just set the properties no null
User userInDB=entityManager.find(userId);
//iterator all the properties, set the property which is not null or empty to the userInDB
entityManager.persist(userInDB);
return "user/show"
}
如图所示,我们必须检查模型的属性,一旦模型有一些深度嵌套的bean,这将是乏味的。
处理这种情况时,您的一般做法是什么?
答案 0 :(得分:0)
最佳做法是在发送部分(字段含义)请求时使用提及的PATCH
方法。然后,应修改请求中存在的所有字段 - 设置为空值,例如
说到PUT
,您不应接受部分请求 - 因为这与标准不兼容。当请求在语法上正确时,您应该修改所有字段,除非DB约束阻止您这样做。因此,如果特定用户可以(就系统而言)将位置设置为空值,则应允许他/她这样做。如果不可能,您应该提出错误的请求异常并返回400状态代码以及消息。