RESTful API 设计:更新 (PUT) 中的不可更改数据是不是应该是可选的?

Posted

技术标签:

【中文标题】RESTful API 设计:更新 (PUT) 中的不可更改数据是不是应该是可选的?【英文标题】:RESTful API design: should unchangable data in an update (PUT) be optional?RESTful API 设计:更新 (PUT) 中的不可更改数据是否应该是可选的? 【发布时间】:2011-06-23 19:45:31 【问题描述】:

我正在实施 RESTful API,我不确定是否存在无法更改的数据的“社区接受”行为。例如,在我的 API 中有一个“文件”资源,该资源在创建时包含许多在创建后无法修改的字段,例如文件的二进制数据,以及与之关联的一些元数据。此外,“文件”可以有书面描述,以及相关的标签。

我的问题涉及对这些“文件”资源之一进行更新。特定“文件”的 GET 将返回与文件关联的所有元数据、描述和标签,以及文件的二进制数据。特定“文件”资源的 PUT 是否应该包含“只读”字段?我意识到它可以以任何一种方式编码:a)在 PUT 数据中包含只读字段,然后验证它们与原始字段匹配(或发出错误),或 b)忽略 PUT 数据中只读字段的存在因为它们无法更改,如果它们不匹配或由于逻辑忽略它们而丢失,则永远不会发出错误。

似乎它可以采取任何一种方式并且可以接受。忽略只读字段的第二种方法更紧凑,因为 API 客户端可以根据需要跳过发送只读数据;这对于知道自己在做什么的人来说似乎很好......

【问题讨论】:

请注意:Roy Fielding 说 PUT 不能用于部分更新。 tech.groups.yahoo.com/group/rest-discuss/message/17421 对于部分更新,请使用 POST。 PUT 用于替换给定 URL 的资源。另见:***.com/a/2443344/48082***.com/a/2391954/48082 【参考方案1】:

就个人而言,这两种方式都可以接受....但是,如果我是你,我会选择选项 A(检查只读字段以确保它们没有被更改,否则会引发错误)。根据您的项目范围,您不能假设消费者深入了解您的 Restful WS,因为他们中的大多数人不阅读文档或 WADL,即使他们是有经验的人。 :)

如果您不立即向消费者提供某些字段为只读的反馈,他们会错误地假设您的 Web 服务会在不重复检查的情况下处理他们所做的所有更改,或 一旦他们发现“不一致”的更新,他们就会向其他人抱怨你的网络服务有问题。

如果只读字段与原始值不匹配,您可以通过两种不同的方式处理此问题...

    不处理请求。发送 409 冲突代码和特定错误消息。 处理请求,发送 200 OK 和一条消息,指出对只读字段所做的更改将被忽略。

【讨论】:

【参考方案2】:

除非只读数据占数据的很大一部分(甚至传输只读数据对网络流量和响应时间有明显影响),否则您应该编写服务以接受只读PUT 中的字段并检查它们是否有更改。输入和输出相同的数据更简单。

这样看:您可以在 PUT 中选择包含只读字段,但您仍然必须/应该在服务中编写代码以检查收到的任何只读字段是否包含预期的价值观。无论哪种方式,您都必须编写只读检查。

禁止 PUT 中的只读字段是一个坏主意,因为这将要求客户端删除他们在 GET 中从您那里收到的字段。这要求客户比他们真正需要的更密切地参与您的数据和语义。客户会认为这是一个令人头疼的问题,一种不必要的复杂性,并且是你给他们增加负担的彻头彻尾的卑鄙手段。获取从您的 GET 接收到的数据,修改一个感兴趣的字段,然后使用 PUT 将其发送回给您,这对于客户来说应该是一次脑力衰竭的简单往返。不必要的时候不要把事情复杂化。

【讨论】:

以上是关于RESTful API 设计:更新 (PUT) 中的不可更改数据是不是应该是可选的?的主要内容,如果未能解决你的问题,请参考以下文章

如何设计一个restful风格的API

Restful API 设计参考原则

RESTful设计要素

http 的 restful api 的 put 请求,参数放在哪儿?

在 RESTful API 中访问对象的版本/修订

RESTful api设计风格