多个 PATCH 请求 REST 端点
Multiple PATCH requests REST End Point
我有一个 Spring Data Rest 项目,它公开了一个由 JPA 和休眠管理的实体。
我使用多个 PATCH 请求更新实体中的多个多对多关系。
所以我将 PATCH 请求发送到端点,实体 url 列表作为每个多对多关系的正文。
补丁请求是同时发生的,所以一个请求被处理,第二个并发请求给出
行已被另一个事务更新或删除(或未保存值映射不正确)
有没有办法同时修补实体?
示例实体就像,
User {
List<Role> roles;
List<Module> modules;
}
角色和模块同时发生补丁请求。
编辑:这是我用来打补丁的angular代码。
var patchRequests = [];
angular.forEach(copy, function (value, property) {
if (angular.isArray(copy[property])) {
// If array contains more than zero elements
if (copy[property].length > 0) {
patchRequests.push(
$http.patch(url,copy[property].join('\n'), {
headers: {
'Content-type': 'text/uri-list'
}
}));
}
}
});
$q.all(patchRequests);
'copy' 对象如下所示
{"roles":["http://localhost:9002/api/roles/1","http://localhost:9002/api/roles/3"],"modules":["http://localhost:9002/api/modules/1"],"subModules":[],"userName":"hrandika","password":"password","email":"h@local","activated":true}
编辑 2:
Spring数据休息只是一个接口
@Repository
public interface UserRepository extends PagingAndSortingRepository<User, Long>{
}
根据 HTTP Patch 规范:
The server MUST apply the entire set of changes atomically and never
provide (e.g., in response to a GET during this operation) a
partially modified representation. If the entire patch document
cannot be successfully applied, then the server MUST NOT apply any of
the changes.
单个补丁请求完成的所有更改都必须是原子的。这是在 Java 中通过使用容器或数据库管理事务实现的。
因此,如果两个客户端向服务器发送补丁,其中一个客户端必须等到第一个客户端完成他的工作,否则就会失败。
由于补丁可以更新任何字段(甚至是其他资源的字段),因此两个单独的补丁请求可能会以不同方式更新同一字段(类似于数据库竞争场景中使用的乐观锁示例)。除此之外,补丁指令通常应包含将状态 1 转换为状态 2 所需的步骤。使用 JSONPatch f.e。一个请求可以从 collection 中删除一个字段,而另一个请求则试图将项目移动到另一个位置。由于这两个请求都依赖于他们当前知道的状态,因此盲目应用这些值可能很危险。
不过,HTTP 补丁规范还提供了有关如何处理多个补丁请求的冲突情况的提示:
A PATCH request can be issued in such a way as to be idempotent,
which also helps prevent bad outcomes from collisions between two
PATCH requests on the same resource in a similar time frame.
Collisions from multiple PATCH requests may be more dangerous than
PUT collisions because some patch formats need to operate from a
known base-point or else they will corrupt the resource. Clients
using this kind of patch application SHOULD use a conditional request
such that the request will fail if the resource has been updated
since the client last accessed the resource. For example, the client
can use a strong ETag [RFC2616] in an If-Match header on the PATCH
request.
因此我建议遵循规范并使用 ETag 和 If-Match HTTP headers 来防止多个补丁请求发生冲突。
我有一个 Spring Data Rest 项目,它公开了一个由 JPA 和休眠管理的实体。 我使用多个 PATCH 请求更新实体中的多个多对多关系。
所以我将 PATCH 请求发送到端点,实体 url 列表作为每个多对多关系的正文。
补丁请求是同时发生的,所以一个请求被处理,第二个并发请求给出
行已被另一个事务更新或删除(或未保存值映射不正确)
有没有办法同时修补实体? 示例实体就像,
User {
List<Role> roles;
List<Module> modules;
}
角色和模块同时发生补丁请求。
编辑:这是我用来打补丁的angular代码。
var patchRequests = [];
angular.forEach(copy, function (value, property) {
if (angular.isArray(copy[property])) {
// If array contains more than zero elements
if (copy[property].length > 0) {
patchRequests.push(
$http.patch(url,copy[property].join('\n'), {
headers: {
'Content-type': 'text/uri-list'
}
}));
}
}
});
$q.all(patchRequests);
'copy' 对象如下所示
{"roles":["http://localhost:9002/api/roles/1","http://localhost:9002/api/roles/3"],"modules":["http://localhost:9002/api/modules/1"],"subModules":[],"userName":"hrandika","password":"password","email":"h@local","activated":true}
编辑 2: Spring数据休息只是一个接口
@Repository
public interface UserRepository extends PagingAndSortingRepository<User, Long>{
}
根据 HTTP Patch 规范:
The server MUST apply the entire set of changes atomically and never provide (e.g., in response to a GET during this operation) a partially modified representation. If the entire patch document cannot be successfully applied, then the server MUST NOT apply any of the changes.
单个补丁请求完成的所有更改都必须是原子的。这是在 Java 中通过使用容器或数据库管理事务实现的。
因此,如果两个客户端向服务器发送补丁,其中一个客户端必须等到第一个客户端完成他的工作,否则就会失败。
由于补丁可以更新任何字段(甚至是其他资源的字段),因此两个单独的补丁请求可能会以不同方式更新同一字段(类似于数据库竞争场景中使用的乐观锁示例)。除此之外,补丁指令通常应包含将状态 1 转换为状态 2 所需的步骤。使用 JSONPatch f.e。一个请求可以从 collection 中删除一个字段,而另一个请求则试图将项目移动到另一个位置。由于这两个请求都依赖于他们当前知道的状态,因此盲目应用这些值可能很危险。
不过,HTTP 补丁规范还提供了有关如何处理多个补丁请求的冲突情况的提示:
A PATCH request can be issued in such a way as to be idempotent, which also helps prevent bad outcomes from collisions between two PATCH requests on the same resource in a similar time frame. Collisions from multiple PATCH requests may be more dangerous than PUT collisions because some patch formats need to operate from a known base-point or else they will corrupt the resource. Clients using this kind of patch application SHOULD use a conditional request such that the request will fail if the resource has been updated since the client last accessed the resource. For example, the client can use a strong ETag [RFC2616] in an If-Match header on the PATCH request.
因此我建议遵循规范并使用 ETag 和 If-Match HTTP headers 来防止多个补丁请求发生冲突。