REST API为“a”设计;“重置为默认值”;活动
我惊讶地发现网上很少提到这个两难问题,这让我怀疑自己是否完全错过了什么REST API为“a”设计;“重置为默认值”;活动,rest,api-design,http-method,Rest,Api Design,Http Method,我惊讶地发现网上很少提到这个两难问题,这让我怀疑自己是否完全错过了什么 假设我有一个名为Settings的单例资源。它是在我的web服务器的init/install上创建的,但是某些用户可以通过RESTAPI修改它,比如说/settings是我的URI。我有一个GET操作来检索设置(作为JSON),还有一个PATCH操作来设置它的一个或多个值 现在,我想让用户在执行任何补丁调用之前,将此资源(或者它的单个属性)重置为默认值-默认值是“init上使用的任何值”。我似乎找不到任何“最佳实践”方法,但
假设我有一个名为
Settings
的单例资源。它是在我的web服务器的init/install上创建的,但是某些用户可以通过RESTAPI修改它,比如说/settings
是我的URI。我有一个GET
操作来检索设置(作为JSON),还有一个PATCH
操作来设置它的一个或多个值
现在,我想让用户在执行任何补丁
调用之前,将此资源(或者它的单个属性)重置为默认值-默认值是“init上使用的任何值”。我似乎找不到任何“最佳实践”方法,但以下是我提出的方法:
DELETE
操作。它毕竟是幂等的,而且(对我来说)很清楚。但是由于URI在DELETE
之后仍然存在,这意味着资源既没有被删除也没有移动到不可访问的位置,这与DELETE
的RESTful定义相矛盾POST
到一个专用的端点,比如/settings/reset
——我真的不喜欢这个,因为它是最明显的非RESTful,因为动词在URI中PATCH
操作,传递一些“default”的替代值,例如null
值。这个问题是操作的结果与输入不同(我将一个属性设置为null
,然后我得到它,它有一个字符串值)/settings/defaults
,然后使用补丁中的响应设置这些值。这似乎与REST没有任何矛盾,但它确实需要为一个看似简单的操作调用两个API
/settings
,并希望在完成后运行一个清理脚本,将/settings
重置回正常状态
该产品不是SaaS(目前),API也不是公共的(比如,网络上的任何人都可以自由访问它们)——因此我可能遇到的受众和潜在的“客户”类型相当小——使用我的产品的开发人员,这些产品部署在他们的私有数据中心或AWS EC2机器中,并且需要用任何语言编写脚本来自动化某些任务,而不是通过UI来完成
这意味着一些技术考虑因素(如缓存)是相关的。人类用户的考虑因素,如API设计在各种资源中的一致性,以及它的易学性,也是相关的。但是“某个第三方爬虫程序能否识别它在给定状态下可以执行的下一个操作”并不是那么重要(这就是为什么我们不实现HATEOAS,或者根本不实现选项方法)
POST在HTTP中有许多有用的用途,包括“此操作不值得标准化”的一般用途
在网络上,你最有可能在提交表单后看到这种情况;该表单可能嵌入到/settings资源的表示中,也可能存在于单独的文档中(这取决于缓存之类的注意事项)。在该设置中,请求的有效负载可能会更改:
POST /settings HTTP/x.y
Content-Type: application/x-www-form-urlencoded
action=restoreDefaults
另一方面:如果此消息的语义值得标准化(即:如果web上的许多资源应该以相同的方式理解“恢复默认值”),那么您可以使用新的方法令牌,将其推进标准化过程并促进采用
因此,在这个定义中,我们将指定,例如,方法的语义是幂等的但不安全的,并且还定义我们可能需要的任何新头
其中有一点与使用POST重置“REST对方法的唯一要求是为所有资源统一定义它们”的想法相冲突。如果我的大多数资源都是典型的CRUD集合,那么普遍认为POST将创建给定类型的新资源
这里有一种紧张气氛,你应该注意:
- 的参考应用程序是万维网
- HTML表单支持的唯一不安全的方法是POST
- 网络取得了灾难性的成功
支持这一点的一个想法是界面是统一的——浏览器不必知道某个标识符是指“集合资源”还是“成员资源”、文档还是图像或其他什么。中间组件(如缓存和反向代理)也是如此。每个人对自我描述的信息都有相同的理解。。。即使是像波斯特这样故意含糊其辞的人
如果您想要一条语义比POST更具体的消息,您需要为它注册一个定义。举个例子,这正是发生在,有人提出了,t
POST /settings HTTP/x.y
Content-Type: application/x-www-form-urlencoded
action=restoreDefaults