REST - 更新部分数据

时间:2016-12-18 10:01:54

标签: rest spring-mvc restful-url

我目前正在编写REST服务和主要使用此REST服务的网站。

型号:

public class User {
    private String realname;
    private String username;
    private String emailAddress;
    private String password;
    private Role role;
    ..
}

查看:

要更新的一种表单

  • 实名
  • 电子邮件地址
  • 用户名

更新角色的另一种形式

第三种形式更改密码

着眼于第一种观点,哪种模式是一种好习惯?

PUT / user / {userId}

imho不是因为表单只包含部分数据(不是角色,不是密码)。所以它无法发送整个用户对象。

PATCH / user / {userId}

可能没问题。是一种很好的方式来实现它:

1)读取当前用户实体

2)

if(source.getRealname() != null) // Check if field was set (partial update)
dest.setRealname(source.getRealname());
.. for all available fields

3)保存目标

POST / user / {userId} / generalInformation

作为realname,email,username

的摘要

谢谢!

2 个答案:

答案 0 :(得分:2)

此方法的一个问题是用户无法使可选字段无效,因为代码未应用值if(input为空且value)为null。 这可能适用于密码或其他必需的实体字段,但是例如,如果您有一个可选的Note字段,则用户无法“清理”该字段。

另外,如果您使用的是普通FORM,则无法使用PATCH方法,只能使用GET或POST。

如果您使用的是Ajax,您可能会对JSON Merge Patch(更简单)和/或JavaScript Object Notation (JSON) Patch(最完整)感兴趣;有关在部分更新和使用PATCH中可以找到的问题的概述,请参阅this page

一点是表单只能发送空值或填充值,而JSON对象属性可以有三种状态:value(update),null(set null)和no-property(ignore)。

我成功使用的实现是ZJSONPATCH

答案 1 :(得分:1)

  

着眼于第一种观点,哪种模式是一种好习惯?

我的建议从一个简单的想法开始:你将如何将其作为HTML中的网页?

您可能从一个提供用户视图的页面开始,其中包含"更新个人资料","更新角色","更改密码"等超链接。单击更新配置文件将加载一个html表单,可能已经填充了一堆默认值。运营商将进行更改,然后提交表单,该表单将向终端发送消息,该终端知道如何解码消息正文并更新模特。

前两个步骤是"安全" - 运营商不提议任何变更。在最后一步中,操作员提议进行更改,因此安全方法不合适。

HTML,作为超媒体格式,仅限于两种方法(GET,POST),因此我们可能会看到浏览器执行类似

的操作
GET  /user/:id
GET  /forms/updateGeneralInformation?:id
POST /updates/generalInformation/:id

您可以使用许多不同的拼写,具体取决于您更喜欢如何整理资源。浏览器并不关心,因为它只是关注链接。

您的API具有相同的灵活性。套件中的第一个技巧应该始终是"我可以使用新资源解决这个问题吗?"。

Ian S Robinson观察到:specialization and innovation depend on an open set。如果您将自己局限于封闭的HTTP方法词汇表,那么您需要创新的开放式集合需要在其他地方使用:RESTful方法是使用一组开放的资源。

配置文件的更新确实听起来像应该是幂等的操作,所以如果可以的话,你想要使用PUT。是否有任何问题:

GET /user/:id/generalInformation
PUT /user/:id/generalInformation

它是一个写,它是幂等的,它是generalInformation资源的完全替代,因此HTTP规范很高兴。

是的,使用单个请求更改多个资源的当前表示形式是有效的HTTP。实际上,这是RFC 7231

描述的方法之一
  

通过使用与较大资源的一部分重叠的状态定位单独标识的资源,可以实现部分内容更新

如果您不想支持多个资源视图并支持每个视图的PUT,您可以通过引入命令队列来应用相同的启发式("添加更多资源和#34;)基础模型。

GET /user/:id/generalInformation
PUT /changeRequests/:uuid

由您决定是将所有变更请求表示为同一集合中的条目,还是具有针对操作子集的变更请求的专门集合。番茄,tomahto。