同上效力
遵循RFC,PUT必须将完整的对象交付给资源。其主要原因是,PUT应该是幂等的。这意味着重复的请求应在服务器上评估为相同结果。
如果允许部分更新,则它不再是幂等的。如果您有两个客户。客户端A和客户端B,则可能会发生以下情况:
客户端A从资源图像中获取图片。其中包含对图像的描述,该描述仍然有效。客户端B放置新图像并相应地更新描述。图片已更改。客户A看到,他不必更改描述,因为它像他希望的那样,只放置了图像。
这将导致不一致,图像附加了错误的元数据!
更令人讨厌的是,任何中介都可以重复该请求。如果它以某种方式决定了PUT失败。
PUT的含义无法更改(尽管您可能会滥用它)。
其他选择
幸运的是,还有另一个选择,这就是PATCH。PATCH是一种允许您部分更新结构的方法。您可以简单地发送部分结构。对于简单的应用程序,这很好。这种方法不能保证是等效的。客户应以以下形式发送请求:
PATCH /file.txt HTTP/1.1
Host: www.example.com
Content-Type: application/example
If-Match: "e0023aa4e"
Content-Length: 20
{fielda: 1, fieldc: 2}
服务器可以返回204(无内容)以标记成功。如果出错,则无法更新结构的一部分。PATCH方法是原子的。
此方法的缺点是,并非所有浏览器都支持此方法,但这是REST服务中最自然的选择。
补丁请求示例:
http : //tools.ietf.org/html/rfc5789#section-2.1
Json修补
json选项似乎非常全面并且是一个有趣的选项。但是对于第三方来说可能很难实现。您必须确定用户群是否可以处理此问题。
这也有些令人费解,因为您需要构建一个小的解释器,该解释器将命令转换为部分结构,您将使用该部分结构来更新模型。该解释器还应检查所提供的命令是否有意义。有些命令会互相抵消。(写入fielda,删除fielda)。我认为您想将此报告给客户端,以限制其调试时间。
但是,如果您有时间,这是一个非常优雅的解决方案。您仍然应该验证字段。您可以将其与PATCH方法结合使用,以保留在REST模型中。但是我认为POST在这里可以接受。
变坏了
如果您决定使用PUT选项,则有些冒险。然后,您至少不应丢弃该错误。用户有一定的期望(数据将被更新),如果您破坏了期望,您将给一些开发人员带来不好的时光。
您可以选择进行标记:409冲突或403禁止访问。这取决于您如何看待更新过程。如果您将其视为一组规则(以系统为中心),那么冲突会更好。诸如此类,这些字段不可更新。(与规则冲突)。如果您将其视为授权问题(以用户为中心),则应返回“禁止”。使用:您无权更改这些字段。
您仍然应该强制用户发送所有可修改的字段。
强制执行此操作的合理选择是将其设置为仅提供可修改数据的子资源。
个人意见
就个人而言,我会去(如果您不必使用浏览器)简单的PATCH模型,然后再使用JSON补丁处理器对其进行扩展。这可以通过区分mimetypes来完成:json补丁的mime类型:
application / json-patch
和json:application / json-patch
使其易于分两个阶段实施。