首页 > 解决方案 > http PUT 可以修改标识符吗?

问题描述

RestfulAPI 中:

PUT /product/{id}

上述http请求是否可以在其body中指定一个不同的id,以便真正改变原始记录的id(假设id在底层存储中技术上是可变的)

这似乎支持. Restful_ 但我不确定,(即使通过谷歌搜索)PUT

任何想法?

标签: httpputrestful-urlidempotent

解决方案


首先,指定PUT为:

PUT 方法请求创建目标资源的状态或将其替换为请求消息有效负载中包含的表示定义的状态。给定表示的成功 PUT 将表明对同一目标资源的后续 GET 将导致在 200 (OK) 响应中发送等效表示。但是,不能保证这样的状态变化是可观察到的,因为在接收到任何后续 GET 之前,目标资源可能会被其他用户代理并行操作,或者可能会受到源服务器的动态处理。

根据该定义,“移动”资源PUT将违反 HTTP 规范,因此REST,因为无法再次通过相同的 URI 检索资源,以防 URI 也应反映更新的 ID 并且不实施重定向。但是,您可以自由使用POST,因为这里的有效负载是根据资源自己的语义处理的。请注意,实际有效负载(资源的状态)的变化并不是真正的问题,但根据规范,URI 的“替换”会是。

根据菲尔丁的说法,资源是可以命名的任何东西,例如某个文档,某处发生的事件的图片。甚至其他资源的集合也可以是资源本身。Fielding 将资源描述为时间到一组等效的实体或值的映射。这里的值可以是资源表示和/或资源标识符。这意味着因此允许资源随时间变化。这种行为每天都可以在网络上看到,即

在论文的第 6.2 章中,Fielding 谈到了 REST 如何应用于 URI。

... REST 中资源的定义基于一个简单的前提:标识符应尽可能不频繁地更改。因为 Web 使用嵌入式标识符而不是链接服务器,所以作者需要一个与超媒体引用的语义密切匹配的标识符,从而允许引用保持静态,即使访问该引用的结果可能会随时间而变化。REST 通过将资源定义为作者打算识别的语义而不是在创建引用时与这些语义对应的值来实现这一点。然后留给作者确保为引用选择的标识符确实标识了预期的语义。...

...一个资源可以有许多标识符。换句话说,当用于访问服务器时,可能存在两个或多个具有等效语义的不同 URI。也可能有两个 URI 导致在访问服务器时使用相同的机制,但是这些 URI 标识两个不同的资源,因为它们的含义不同。

语义是分配资源标识符和用表示填充这些资源的行为的副产品。服务器或客户端软件在任何时候都不需要知道或理解 URI 的含义。...

虽然资源的内容可能会随着时间而改变,因此资源可能会使用不同的内部记录 ID(或类似的),但产品是否真的通过给它一个不同的 ID 而改变(那么多)是值得怀疑的?在这种情况下,最好不要在 URI 本身中使用内部产品 ID,而是使用任意值,例如一般的 UUID。由于客户端不应解释或尝试从 URI 中提取含义,因此 URI 中的字符实际上在 REST 架构中并不那么重要。相反,应该使用有意义的链接关系来允许客户端确定 URI 的使用。

在 REST 体系结构中,客户端仅使用协商的(因此受支持的)表示,因此仅使用服务器提供的信息。如果服务器需要来自客户端的输入,它将为客户端提供一个表单表示,客户端知道如何采取行动。在 Web 产品上,通常可以通过专用元素(例如链接或搜索字段)列出或搜索产品,其中的可供性(基本上您可以使用该元素做什么)是明确的。在这样的系统中,在其自己的结果页面上显示的产品列表可以使用自定义的链接关系名称提示客户有关具体产品的信息,并附上一个链接,如果客户有兴趣与该特定产品进行交互,它只会调用该链接。因此,客户端不必解析或解释 URI,而只需知道链接关系本身的含义或用例。在 REST 架构中也应该使用相同的交互模型和可供性概念。

可以设置(临时)重定向到新产品“页面”,以允许仍具有旧版本产品 URI 的客户端仍与该资源交互并获得有关新位置的更新。这基本上将允许任何 HTTP 操作像以前一样工作。特别是由于缓存,某些客户端可能还没有意识到位置变化,因为它们可能会被本地或中间缓存提供仍然足够新鲜的表示。因此,重定向将是一个合理的选择。

总之:

  • 因此,使用PUT基本上“移动”资源并生成不同的目标 URI 违反了 HTTP 规范,因此违反了 REST。POST应改为使用后备。
  • 避免在 URI 中包含产品的内部 ID,以将产品的标识符与实际 URI 分离,以允许即使内部标识符发生更改也可以重用 URI。这可能需要在服务器端映射哪个产品在哪个 URI 上公开。这与 Mike Amundsen 相得益彰,他声称您的数据模型不是您的对象模型不是您的资源模型不是您的可供性模型
  • 实现从旧 URI 到新 URI 的(临时)重定向,以允许旧客户端仍然与产品交互

推荐阅读