PUT 端点处理动态资源存在的创建/更新

问题描述 投票:0回答:1

我有一个场景,我正在设计一个 RESTful API 端点来管理购物车中的商品。端点定义如下:

PUT /carts/{{cartId}}/items

请求的预期 JSON 正文是:

{
    "sku": 100001,
    "quantity": 1,
    "price": 49.95
}

服务器端的当前实现有一种行为,我发现这对于减少负载很有用。如果购物车中已存在该商品,则数量加 1;否则,它会使用提供的详细信息将新商品添加到购物车。

现在,我关心的是这是否符合 RESTful 原则中 PUT 方法的定义。我的理解是 PUT 应该替换整个资源,或者如果不存在则创建一个新资源。

这是我的具体问题:

  1. 当前的实现是否违反了 PUT 定义,给定 它不会替换整个资源,而是对其进行修改 以特定方式(添加数量+1)?
  2. 如果当前的实现与 PUT 方法的定义不一致,那么更合适的 HTTP 方法是什么 对于这种情况?
  3. 是否有任何最佳实践或替代方法来处理此类行为取决于存在的情况 请求时的资源?
rest httprequest api-design restful-url
1个回答
0
投票

首先提醒一下:PUT 的语义当前由 RFC 9110 定义。 它们本质上是:“请使您当前对该资源的表示看起来像所附的表示。”

例如,如果我们想要修复网页中的拼写错误,我们将使用此 HTTP 方法。通用编辑器会获取 HTML 的副本(通过 GET /example),对本地副本进行更改,然后将编辑后的网页副本发送回服务器(通过 PUT /example)。

REST 的 统一接口 约束表明每个人都应该以相同的方式理解消息。

因此

PUT /carts/{{cartId}}/items

应该 意味着

完全相同
PUT /example

当前的实现是否违反了 PUT 定义,因为它不会替换整个资源,而是以特定方式对其进行修改(添加数量 +1)?

因此有两个重要的想法需要区分。

尝试为资源的 PUT 消息创建专门的含义是错误的(受统一接口约束)。

但是....

统一接口约束适用于请求/响应语义,而不适用于资源的实现

HTTP 并不试图要求 GET 的结果是安全的。它所做的是要求操作的语义是安全的,因此如果发生任何导致财产损失的结果,则这是实现的错误,而不是接口或该接口的用户的错误 - Fielding, 2002年

出于同样的原因,您可以在 PUT 处理程序的实现中做任何您想做的事情...但是,如果由于您实际执行的操作与消息所要求的内容之间的差异而导致昂贵的结果,那么律师将得出结论:您的实现是有错的,而不是客户的错,因为客户认为您理解 PUT 的含义。


如果当前的实现与 PUT 方法的定义不一致,那么对于这种情况更合适的 HTTP 方法是什么?

发布


是否有任何最佳实践或替代方法来处理此类场景

主要是这样的:您的 API 是一个外观,其作用类似于通用文档存储。您的资源模型是您提供的可供性的集合,以便可以使用通用 HTTP 消息向您发送信息,或向您请求信息。

我们的目标不是创建专门的消息来触发有用的工作;而是创建特定的消息来触发有用的工作。相反,目标是设计一个资源模型,响应通用消息,执行有用的工作。

Jim Webber 描述它的方式:“专业化和创新取决于开放集”。对于 SOAP,我们有一组可扩展的消息被发送到一组固定的端点。如果你想做一些新的事情,你就发明了一条新的信息。 REST 采用另一种方法 - 消息集很小,但我们可以在资源集中进行尽可能多的创新。

© www.soinside.com 2019 - 2024. All rights reserved.