REST: 用一个请求更新多个资源 - 是标准的还是应该避免的?

14 浏览
0 Comments

REST: 用一个请求更新多个资源 - 是标准的还是应该避免的?

一个简单的REST API:\n

    \n

  • GET: items/{id} - 返回具有给定id的项目的描述
  • \n

  • PUT: items/{id} - 更新或创建具有给定id的项目
  • \n

  • DELETE: items/{id} - 删除具有给定id的项目
  • \n

\n现在是有问题的API扩展部分:\n

    \n

  • GET: items?filter - 返回与过滤器匹配的所有项目id
  • \n

  • PUT: items - 根据JSON有效载荷的描述,更新或创建一组项目
  • \n

  • [[DELETE: items - 根据JSON有效载荷的描述,删除一组项目]] <- 不正确
  • \n

\n我现在对PUT/DELETE items/{id}中可以轻松访问的删除和更新操作很感兴趣。\n问题: 提供这样的API是否常见?\n替代方案: 在单连接多请求的时代,发出多个请求是廉价的,并且由于更改要么成功要么失败,因此工作更具原子性,但在NOSQL数据库时代,即使请求处理由于任何原因而死机或出现内部服务器错误,列表中的更改可能已经发生。\n[更新]\n在考虑了白宫网络标准维基百科:REST示例之后,现在提出以下示例API:\n一个简单的REST API:\n

    \n

  • GET: items/{id} - 返回具有给定id的项目的描述
  • \n

  • PUT: items/{id} - 更新或创建具有给定id的项目
  • \n

  • DELETE: items/{id} - 删除具有给定id的项目
  • \n

\n顶级资源API:\n

    \n

  • GET: items?filter - 返回与过滤器匹配的所有项目id
  • \n

  • POST: items - 根据JSON有效载荷的描述,更新或创建一组项目
  • \n

\n不支持和禁止在/items上使用PUT和DELETE。\n使用POST似乎是一个不错的选择,因为它是在封闭资源中创建新项目的一种方式,而不是替换而是添加。\nHTTP语义POST中写道:\n

\n通过追加操作扩展数据库\n

\n而PUT方法则需要替换整个集合以返回等效表示,如HTTP语义PUT中引述的:\n

\n成功的PUT操作将暗示后续对同一目标资源的GET将返回等效表示,以200(OK)响应的形式返回。\n

\n[更新2]\n对于多个对象的更新方面,似乎更一致的选择是PATCH方法。PUT和PATCH之间的区别在草案RFC 5789中描述为:\n

\nPUT和PATCH请求之间的区别反映在服务器处理封闭实体以修改由请求URI标识的资源的方式上。在PUT请求中,封闭实体被视为对原始服务器上存储的资源的修改版本,并且客户端请求替换存储的版本。然而,使用PATCH,封闭实体包含一组说明,描述应如何修改当前驻留在原始服务器上的资源以生成新版本。PATCH方法影响由请求URI标识的资源,并且它也可能对其他资源产生副作用; 即应用程序可能通过应用PATCH来创建新资源或修改现有资源。\n

\n因此,与POST相比,PATCH可能也是一个更好的选择,因为PATCH允许更新,而POST只允许追加,意味着添加而没有修改的机会。\n因此,POST在这里似乎是错误的,我们需要更改我们提出的API为:\n一个简单的REST API:\n

    \n

  • GET: items/{id} - 返回具有给定id的项目的描述
  • \n

  • PUT: items/{id} - 更新或创建具有给定id的项目
  • \n

  • DELETE: items/{id} - 删除具有给定id的项目
  • \n

\n顶级资源API:\n

    \n

  • GET: items?filter - 返回与过滤器匹配的所有项目id
  • \n

  • POST: items - 根据JSON有效载荷的描述,创建一个或多个项目
  • \n

  • PATCH: items - 根据JSON有效载荷的描述,创建或更新一个或多个项目
  • \n

0
0 Comments

REST架构风格中,允许使用一个请求来更新多个资源。实际上,这里的关键是将这些多个资源看作是一个容器,并将其视为一个单一的资源。例如,可以假设ID列表标识了一个包含多个其他资源的资源。

在维基百科的示例中,他们也谈到了复数形式的资源。

在维基百科的示例中,他们指出PUT和POST的处理方式不同,并且建议使用POST来创建一个或多个新实体。

问题的出现是因为对于使用REST进行多资源更新的标准并没有统一的规定。有些人认为使用POST来创建新资源更为合适,而有些人则认为使用PUT更符合REST的原则。

解决这个问题的方法是根据自己的需求和实际情况进行选择。如果需要创建新资源,可以使用POST请求,如果需要更新已有资源,可以使用PUT请求。根据REST的原则,使用PUT请求来更新多个资源可能更为合适,因为PUT请求是幂等的,可以确保请求的可重复性。

总之,对于使用REST进行多资源更新的方法并没有统一的标准,选择使用POST还是PUT取决于具体的需求和实际情况。根据REST的原则,使用PUT请求来更新多个资源可能更为合适。

0
0 Comments

REST: Updating Multiple Resources With One Request - Is it standard or to be avoided?

有时候,您可能需要执行原子批量操作或其他与资源相关的操作,而这些操作并不适合简单的REST API的典型方案,但如果您需要它,就无法避免使用它。

关于"是否标准"的问题,没有普遍接受的REST API标准,所以很难回答。但是通过查看一些常被引用的API设计准则,比如jsonapi.org、restfulapi.net、微软API设计指南或IBM的REST API约定,它们都没有提到批量操作,可以推断出这些操作通常不被视为REST API的标准特性。

不过,谷歌的API设计指南是一个例外,它提到了可以通过使用冒号将自定义方法与资源关联起来,例如:https://service.name/v1/some/resource/name:customVerb,它还明确提到了批量操作作为用例。

根据谷歌的API指南,您可以按照以下方式处理您提供的示例案例:

POST /api/items:batchUpdate

此外,一些公共API决定提供一个集中的/batch端点,例如谷歌的Gmail API。

此外,正如在restfulapi.net上提到的,还有一个资源"存储"的概念,可以通过PUT一次存储和检索整个项目列表,但此概念不适用于服务器管理的资源集合。

回答了您的原始问题后,这里是另一种解决问题的方法,这种方法尚未被提及。请注意,这种方法有些非传统,看起来不像典型的REST API端点命名方案那样漂亮。我个人并不使用这种方法,但我仍然认为它值得一试 🙂

这个想法是,您可以通过端点路径命名方案将对资源的CRUD操作与其他与资源相关的操作(例如批量操作)区分开来。

例如,考虑一个允许您对"company"资源执行CRUD操作的RESTful API,您还希望执行一些与"company"资源相关的操作,这些操作不适合与通常与restful api相关联的基于资源的CRUD方案,比如您提到的批量操作。

现在,您可以区分以下路径:

/api/companies/items - 即公司资源的集合

/api/companies/ops - 即与公司资源相关的操作

对于"items",应用通常的RESTful API HTTP方法和资源URL命名方案,例如:

POST /api/companies/items

GET /api/companies/items

GET /api/companies/items/{id}

DELETE /api/companies/items/{id}

PUT /api/companies/items/{id}

现在对于与公司相关的操作,您可以使用/api/companies/ops/路由前缀,并通过POST调用操作。

POST /api/companies/ops/batch-update

POST /api/companies/ops/batch-delete

POST /api/companies/ops/garbage-collect-old-companies

POST /api/companies/ops/increase-some-timestamps-just-for-fun

POST /api/companies/ops/perform-some-other-action-on-companies-collection

由于POST请求不一定会导致创建资源,因此在这里使用POST方法是正确的:

此外,还有一个观点认为,谷歌的冒号约定从美学角度来看有点刻意。当发明一个新的动词时,更常见的做法是在其后追加斜杠并将其POST到该位置- POST /api/items/batch-update。我完全承认存在一个缺点,即现在您有一个保留字,不能用于子关联,如果需要子关联的话,但对于更干净的URL,我愿意做出这个牺牲。

REST更多地是一个"概念"而不是一个"标准"。它在资源如何传输方面只施加了非常少的限制,并且没有详细规定REST API应该如何设计,因此将其留给开发人员来决定如何处理事情。由您的团队/公司定义您的REST API运营规则。存在一些被认为是"好的"设计准则,也有一些被认为是"不好的",然而,说它是一个"糟糕的标准"并不完全公正地对待REST作为一个概念/理念,有点误导性。

0
0 Comments

REST:一次请求中更新多个资源-是标准还是应该避免?

在标准REST约定中,并不支持在单个调用中支持删除、创建和更新。但有一种可能是使用特殊的“批处理”服务将这些调用组合在一起。

解决方法是提供一个特殊的“批处理”服务,允许将多个请求组合在一起。这个服务会返回每个嵌入请求的状态码。

如果可以使用HTTP/2,那么单个批处理方案可能是不必要的,因为多个调用的性能开销可能非常低。

另一种解决方法是使用HTTP/2,因为它使得许多传统的性能技巧都过时了。你可以从单个连接中并行处理请求。

还可以创建一个专门的批处理资源,如果直接响应处理时间太长的话,可以将请求存储在这个资源中并在后台进程中并行处理。客户端可以轮询以检查处理是否完成。

另一个解决方法是创建一个任务调度器或工作流处理器。可以为批处理指定可以并行处理的部分和形成一个序列的部分。

批处理可以简化逻辑,并且非常适合用于REST API测试。

0