【问题标题】:What is the most RESTful way to update a resource in a non-idempotent way?以非幂等方式更新资源的最 RESTful 方式是什么?
【发布时间】:2019-05-15 02:21:16
【问题描述】:

更新部分资源的最 RESTful 方式是什么,其中资源的生成是在服务器端完成的,而不是在客户端。这不是幂等操作,因为服务器上的支持数据可能会在请求之间发生变化。

我正在创建一个 Rest API,并且我已经做出了一个设计选择,我非常确定前进的道路。

我有一个想要刷新的资源,其中包括根据支持数据创建一个大型 json blob,然后将该 json blob 保存到数据库中,然后再将其返回给用户。

我的问题是,执行此操作的最 RESTful 方式是什么?由于客户端不执行计算,而且它也不是幂等的,因为每次调用之间数据集可能会发生变化,我觉得使用 PUT 是不自然的。

我选择了一个 POST,但这也不对。

第三种选择是有一个描述刷新动作的子资源 - 这也感觉不正确。

例如,我有一个文档:

GET /document/<documentId>

这将返回类似:

"body": {
    "createdAt": "2019-01-01 12:00:00",
    "updatedAt": "2019-01-01 13:00:00",
    "name": "example",
    "location": "example",
    "city": "example"
}

这些字段是由服务器在创建文档时生成的,客户端不会更新它们。

为了让客户端发出他们希望服务器重新生成文档的信号,我决定:

POST /document/<documentId>
"body": {
   "param1": "updatedparam1",
   "param2": "updatedparam2"
}

另一种方法是执行以下操作:

POST /document/<documentId>/refresh
"body": {...}

但这感觉更像是 RPC 调用而不是 REST。

这在逻辑上有意义吗?我没有看到很多建议 POST 可以针对单个资源而不是集合。

如果我可以扩展任何内容,请告诉我,我一直在努力解决这个问题,可能错过了一些东西。

【问题讨论】:

    标签: rest web-applications architecture api-design


    【解决方案1】:

    我选择了一个 POST,但这也不对。

    POST 是fine

    HTTP 语义包括有关invalidating 缓存资源表示的规则。据推测,当您告诉服务器重新生成文档时,您不想自己继续使用旧副本。因此,请求的目标 uri 应该与您用于 GET 资源的目标 uri 相同。

    所以:

    POST /document/<documentId>
    

    是一个好的开始。

    假设语义匹配,另一种选择是使用PATCH - 如果您正在做的是为表示提议替换值,那么这是一个合适的选择。在这种情况下,请求的主体应该是“补丁文件”。当然,您可以定义自己的补丁文件类型;通用客户端可能已经了解RFC-6902:JSON PatchRFC-7386:JSON Merge Patch 的一种或多种标准,因此您可以通过支持一种或多种标准格式来节省一些工作。

    我没有看到很多关于 POST 可以针对单个资源而不是集合的建议。

    REST 的部分要点是资源支持uniform interface - “单一资源”和“集合资源”看起来相同。从历史上看,early specifications for POST 有点不走运,很容易被误解为 CREATE。

    但一般客户不知道也不关心您在 Web 表单中指定的资源是否是“集合资源”;它只是打包数据并发送请求,确信服务器会知道该做什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-29
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多