在 REST Api 调用中批量更新 collection 的最佳实践
Best practice to batch update a collection in a REST Api call
您好,我正在寻找 API 设计的最佳实践,以通过 API 调用批量更新 collection。
我的 collection 有 URL /api/v1/cars 我想更新 collection 中的所有汽车以添加当前时间的时间戳。
{
data: [
{
manufacturer: 'Porsche',
timestamp: ...
},
{
manufacturer: 'BMW',
timestamp: ...
}
{
manufacturer: 'Peugeot',
timestamp: ...
}
}
我考虑了几个选项,但我想不出什么是最佳做法。
应该是:
1/ 建模为另一个资源,例如 POST api/v1/cars/updateTimestamp
2/ 作为查询参数传递:PUT api/v1/cars?updateTimestamp
3/ 传入请求正文:
POST api/v1/cars
{"operation":"Update timestamps"}
我想强调的是,整个处理应该在 back-end 上完成,而不是由客户端传递。
对于后端发生的任何复杂处理,都会发生同样的问题。
在这种情况下,我怎样才能保留 API RESTy。
非常感谢您 help/any 指向相关资源的指针。
我会做一个 PUT 来做一个更新操作。 PUT 用于更新对象,POST 用于创建。您可以使用查询参数指定字段。
- POST /api/v1/cars > 制造新车
- PUT /api/v1/cars > 根据对象中的 id 更新汽车。你可以
如果你想使用没有 cars/:id 的路线,也可以创建一条路线
id 对所有汽车对象进行更新(这似乎不会发生在
许多应用程序)。
- GET /api/v1/cars > 列出所有汽车
- GET /api/v1/cars/:id > 列出一辆车。
回答你的问题。您想要更新所有汽车对象。在那种情况下,我会使用 PUT /api/v1/cars 并指定一个 /api/v1/cars/:id 来对一辆车进行更新,尽管我不明白你为什么要实现这个。如果是一次性操作,我会更新数据库中的所有汽车,而不是创建 API 路线。
由于在 HTTP 中没有定义部分 PUT
,您要么需要为每个资源发送整个实体以进行更新,要么使用一些其他操作。
POST
由于 POST
是一个 all-purpose 操作,您可以使用它在服务器上创建一个 short-living 临时资源(甚至不需要 own URL).收到后,服务器可以更新所有指定条目或一般所有条目,并提供一些 field-value 组合(某些 table 更改可能是必要的,但如果该列在关系数据库中尚不清楚)
一个简单的请求可能如下所示:
POST /api/v1/cars/addAttributes HTTP/1.1
Host: example.org
Content-Length: 24
Content-Type: application/json
If-Match: "abc123"
{
"timestamp": "..."
}
这种方法的优点是它可以随时发送到服务器,即使事先不知道当前状态。然而,这也有某些条目被更新的危险,这些条目不应该受到影响。这可以通过指定指向某个 version-hash 并在每次实体更新时更改的 If-Match
header 来影响,或者通过向 JSON 添加某个限制器来影响body 服务器也必须理解。
补丁
类似于POST
,可以向服务器发送任何内容,PATCH
用于修改资源。单个请求可能会同时更新多个资源,但是,客户端需要定义将资源从状态 A 转换为状态 B 的必要步骤。因此,客户端还需要拥有资源的最新状态才能成功将资源转换为最新状态(-> ETag 和 If-Modified HTTP headers)
对所提供示例的 JSON Patch 请求因此可能如下所示:
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
是Porsche
、BMW
和Peugeot
资源的唯一标识符。
PATCH
指定请求必须是原子的,这意味着所有指令或 none 指令都成功,这也为 table.[=30 带来了一些事务要求=]
讨论
如前所述,在 POST
请求中,只要服务器能够理解您发送的内容,您就可以向服务器发送任何您想要的内容。因此,如何设计请求结构(以及服务器逻辑)取决于您。
另一方面,PATCH
,尤其是 JSON Patch
定义了一些严格的规则和预定义的操作,通常用于传统修补。交易要求可能是一种负担,但也是一种好处。除此之外,PATCH
尚未最终确定并且仍在 RFC 中,尽管它已经广泛可用。
您好,我正在寻找 API 设计的最佳实践,以通过 API 调用批量更新 collection。
我的 collection 有 URL /api/v1/cars 我想更新 collection 中的所有汽车以添加当前时间的时间戳。
{
data: [
{
manufacturer: 'Porsche',
timestamp: ...
},
{
manufacturer: 'BMW',
timestamp: ...
}
{
manufacturer: 'Peugeot',
timestamp: ...
}
}
我考虑了几个选项,但我想不出什么是最佳做法。
应该是:
1/ 建模为另一个资源,例如 POST api/v1/cars/updateTimestamp
2/ 作为查询参数传递:PUT api/v1/cars?updateTimestamp
3/ 传入请求正文:
POST api/v1/cars
{"operation":"Update timestamps"}
我想强调的是,整个处理应该在 back-end 上完成,而不是由客户端传递。 对于后端发生的任何复杂处理,都会发生同样的问题。 在这种情况下,我怎样才能保留 API RESTy。
非常感谢您 help/any 指向相关资源的指针。
我会做一个 PUT 来做一个更新操作。 PUT 用于更新对象,POST 用于创建。您可以使用查询参数指定字段。
- POST /api/v1/cars > 制造新车
- PUT /api/v1/cars > 根据对象中的 id 更新汽车。你可以 如果你想使用没有 cars/:id 的路线,也可以创建一条路线 id 对所有汽车对象进行更新(这似乎不会发生在 许多应用程序)。
- GET /api/v1/cars > 列出所有汽车
- GET /api/v1/cars/:id > 列出一辆车。
回答你的问题。您想要更新所有汽车对象。在那种情况下,我会使用 PUT /api/v1/cars 并指定一个 /api/v1/cars/:id 来对一辆车进行更新,尽管我不明白你为什么要实现这个。如果是一次性操作,我会更新数据库中的所有汽车,而不是创建 API 路线。
由于在 HTTP 中没有定义部分 PUT
,您要么需要为每个资源发送整个实体以进行更新,要么使用一些其他操作。
POST
由于 POST
是一个 all-purpose 操作,您可以使用它在服务器上创建一个 short-living 临时资源(甚至不需要 own URL).收到后,服务器可以更新所有指定条目或一般所有条目,并提供一些 field-value 组合(某些 table 更改可能是必要的,但如果该列在关系数据库中尚不清楚)
一个简单的请求可能如下所示:
POST /api/v1/cars/addAttributes HTTP/1.1
Host: example.org
Content-Length: 24
Content-Type: application/json
If-Match: "abc123"
{
"timestamp": "..."
}
这种方法的优点是它可以随时发送到服务器,即使事先不知道当前状态。然而,这也有某些条目被更新的危险,这些条目不应该受到影响。这可以通过指定指向某个 version-hash 并在每次实体更新时更改的 If-Match
header 来影响,或者通过向 JSON 添加某个限制器来影响body 服务器也必须理解。
补丁
类似于POST
,可以向服务器发送任何内容,PATCH
用于修改资源。单个请求可能会同时更新多个资源,但是,客户端需要定义将资源从状态 A 转换为状态 B 的必要步骤。因此,客户端还需要拥有资源的最新状态才能成功将资源转换为最新状态(-> ETag 和 If-Modified HTTP headers)
对所提供示例的 JSON Patch 请求因此可能如下所示:
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
是Porsche
、BMW
和Peugeot
资源的唯一标识符。
PATCH
指定请求必须是原子的,这意味着所有指令或 none 指令都成功,这也为 table.[=30 带来了一些事务要求=]
讨论
如前所述,在 POST
请求中,只要服务器能够理解您发送的内容,您就可以向服务器发送任何您想要的内容。因此,如何设计请求结构(以及服务器逻辑)取决于您。
PATCH
,尤其是 JSON Patch
定义了一些严格的规则和预定义的操作,通常用于传统修补。交易要求可能是一种负担,但也是一种好处。除此之外,PATCH
尚未最终确定并且仍在 RFC 中,尽管它已经广泛可用。