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
  • 如果以上其中一项被认为是最佳实践,或者如果有一项我没有在上面列出,我很想听听

    编辑:

    我的特定项目有一些属性可以简化这个问题,但我最初没有提到它们,因为我的目标是让这个线程作为将来试图解决相同问题的任何人的参考。我想确保这个讨论是通用的,对其他人有用,但对我也有用。为此,我将附加以下内容

    在我的例子中,我正在为现有产品设计API。它有一个面向普通用户的web界面,但也有一个REST(ish)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