在 REST Api 调用中批量更新集合的最佳实践 [英] Best practice to batch update a collection in a REST Api call

查看:21
本文介绍了在 REST Api 调用中批量更新集合的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我正在寻找有关 API 设计的最佳实践,以便通过 API 调用批量更新集合.

Hi I'm looking for best practices with API design to batch update a collection with an API call.

我的收藏有 URL/api/v1/cars,我想更新收藏中的所有汽车以添加当前时间的时间戳.

My collection has URL /api/v1/cars and I would like to update all the cars in the collection to add a timestamp of the current time.

{
    data: [
    {
        manufacturer: 'Porsche',
        timestamp: ...
    },
    {
        manufacturer: 'BMW',
        timestamp: ...
    }
    {
        manufacturer: 'Peugeot',
        timestamp: ...
    }
}

我想了几个选项,但我不知道什么是最佳做法.

I thought about a few options but I can't figure what is the best practice.

应该是:

1/建模为另一个资源,例如 POST api/v1/cars/updateTimestamp

1/ Modelled as another resource such as POST api/v1/cars/updateTimestamp

2/作为查询参数传递:PUT api/v1/cars?updateTimestamp

2/ Passed as a query parameter: PUT api/v1/cars?updateTimestamp

3/传入请求体:

POST api/v1/cars 
{"operation":"Update timestamps"}

我想强调的是,整个处理应该在后端完成,而不是由客户端传递.后端发生的任何复杂处理都会发生同样的问题.在这种情况下,我如何保留 API RESTy.

I'd like to emphasize that the whole processing should be done on the back-end and not passed by the client. Same problem would happen for any complex processing that happens on the back end.. How could I keep the API RESTy in this case.

非常感谢您的帮助/任何指向相关资源的指针.

Thanks a lot for your help/any pointer to relevant ressources.

推荐答案

由于在 HTTP 中没有定义部分 PUT,你要么需要为每个资源发送整个实体来更新或使用一些其他操作.

As there is no partial PUT defined in HTTP, you either need to send the whole entity for each resource to update or use some other operations.

由于 POST 是一个通用操作,您可以使用它在服务器上创建一个短暂的临时资源(它甚至不必具有 自己的网址).收到后,服务器可以更新所有指定的条目或所有条目,通常使用一些提供的字段值组合(如果在关系数据库中尚不知道该列,则可能需要更改某些表)

As POST is an all-purpose operation you can use it to create a short-living temporary resource at the server (which further does not even have to have an own URL). On receipt the server can update either all specified entries or all entries in general with some provided field-value combination (certain table alterering may be necessary though if the column is not yet know in relational databases)

一个简单的请求可能如下所示:

A simple request may look like this:

POST /api/v1/cars/addAttributes HTTP/1.1
Host: example.org
Content-Length: 24
Content-Type: application/json
If-Match: "abc123"

{
  "timestamp": "..."
}

这种方法的优点是它可以随时发送到服务器,即使事先不知道当前状态.然而,这也有某些条目被更新的危险,而这些条目不应受到影响.这可以通过指定 If-Match 标头来影响,该标头指向某个版本哈希并在每次实体更新时更改,或者通过向 JSON 主体添加某个限制器,服务器也可以必须明白.

This approach has the advantage that it could be sent to the server anytime, even without prior knowledge of the current state. This, however, also has the danger that certain entries get updated which shouldn't be affected. This can either be influenced by specifying an If-Match header, which points to a certain version-hash and is changed on every entity update, or by adding a certain restrictor to the JSON body which the server also has to understand.

类似于POST,它可以向服务器发送任何东西,PATCH 用于修改资源.单个请求显式可以一次更新多个资源,但是客户端需要定义必要的步骤将资源从状态 A 转换为状态 B. 因此,客户端也需要拥有资源的最新状态才能成功将资源转换为其最新状态(-> ETag 和 If-Modified HTTP 标头)

Similar to POST, which can literally send anything to the server, PATCH is intended for modification of resources. A single request explicitely may update multiple resources at once, however, the client needs to define the necessary steps to transform the resources from state A to state B. Therefore, the client also needs to have the latest state of the resource in order to successfully transform the resource to its newest state (-> ETag and If-Modified HTTP headers)

针对所提供示例的 JSON Patch 请求可能如下所示:

A JSON Patch request for the provided example may therefore look like this:

PATCH /api/v1/cars HTTP/1.1
Host: example.org
Content-Length: 215
Content-Type: application/json-patch+json
If-Match: "abc123"

[
  { "op": "add", "path": "/data/1", "value": [ "timestamp", "..." ] },
  { "op": "add", "path": "/data/2", "value": [ "timestamp", "..." ] },
  { "op": "add", "path": "/data/3", "value": [ "timestamp", "..." ] }
]

其中/data/1/data/2/data/3资源的唯一标识符保时捷宝马标致.

PATCH 指定请求必须是原子的,这意味着要么所有指令都成功,要么不成功,这也给表带来了一些事务要求.

PATCH specifies that a request has to be atomic which means that either all or none of the instructions succeed which also brings some transaction requirements to the table.

正如已经提到的,在 POST 请求中,您可以从字面上向服务器发送任何您想要的内容,至少只要服务器能够理解您发送的内容.因此,如何设计请求结构(以及服务器逻辑)取决于您.

As already mentioned, in POST requests you can literally send anything you want to the server at least as long as the server is capable of understanding what you are sending. It is therefore up to you how you design the request structure (and the server logic as well).

PATCH 另一方面,特别是 JSON Patch 定义了一些严格的规则和预定义的操作,通常是传统的补丁.交易要求可能是一种负担,但也可能是一种好处.除此之外,PATCH 还不是最终版本,尽管它已经广泛可用,但仍在 RFC 中.

PATCH on the other hand, especially with JSON Patch defines some strict rules and predefined operations typically to traditional patching. The transaction requirement can be a burden but also a benefit. In addition to that, PATCH is not yet final and still in RFC though it is already widely available.

这篇关于在 REST Api 调用中批量更新集合的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆