更新实体的宁静应用程序

时间:2015-07-19 10:12:38

标签: spring rest

给定一个控制器,它将为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,这将是乏味的。

处理这种情况时,您的一般做法是什么?

1 个答案:

答案 0 :(得分:0)

最佳做法是在发送部分(字段含义)请求时使用提及的PATCH方法。然后,应修改请求中存在的所有字段 - 设置为空值,例如

说到PUT,您不应接受部分请求 - 因为这与标准不兼容。当请求在语法上正确时,您应该修改所有字段,除非DB约束阻止您这样做。因此,如果特定用户可以(就系统而言)将位置设置为空值,则应允许他/她这样做。如果不可能,您应该提出错误的请求异常并返回400状态代码以及消息。