在 Java 中编写 REST-API 时,PATCH 方法请求将请求实体中描述的一组“更改”应用于由 Request-URI 标识的资源。 (参见:https://datatracker.ietf.org/doc/html/rfc5789)
给出以下资源:
{
productId: 7,
name: "container",
contactPerson: "peter",
price: 12
}
使用 PATCH,我应该能够将“contactPerson”设置为 NULL,同时不触及其他字段,如下所示:
{
productId: 7,
contactPerson: null
}
在 Java 生态系统中,考虑到这里最相关的库需要对其提供全面支持,我如何才能以良好的方式实现这一点:
Java 可选
除其他外,我尝试了 Java-Optional,虽然它最初似乎有效,但它是错误的工具,因为可选不应该包含 NULL 值,但也应该可以在内部显式地将值设置为 NULL一个补丁(而不是省略它)。
例如,以下内容最初看起来不错(此处为必需的名称字段 = false 且可空 = false):
@Schema(required = false, nullable = false)
Optional<@NotNull @Size(max = 255) String> name = Optional.empty();
当请求中缺少名称字段时,Hibernate 验证器认为违反了 @NotNull 注释,我觉得这很奇怪,因为注释位于可选通用声明中(而不是直接在可选中)
JsonNullable
Jackson 提供了 JsonNullable 注释。虽然这是完成该任务的正确工具,并且似乎支持 openapi,但它似乎不支持 hibernate validator,至少我找不到有关它的信息。
验证
问题似乎主要出在 Bean 验证注释的验证过程中,这对于 API 来说很重要。
@Size(255)
、@Email
等注释时,有要求......
--
Java 生态系统的那些主要库是否涵盖了 REST-PATCH?如果是,建议的支持方式是什么?
如何在请求正文中获取键值映射,其中键与字段名称匹配。
@PatchMapping("/boxes/{id}")
public Box patchBox(@PathVariable Long id, @RequestBody Map<String, Object> values) throws JsonMappingException {
return boxService.patchBox(id, values);
}
那么字段值为空的情况将不会与请求中缺少该字段的情况重叠,并且您可以使用ObjectMapper自动仅更新请求中传入的那些字段。
@Override
@Transactional
public Box patchBox(Long id, Map<String, Object> values) throws JsonMappingException {
Box box = entityManager.find(Box.class, id);
objectMapper.updateValue(box, values);
return box;
}
当然,您无法验证查询中的字段值,但您会自动验证其字段更新为这些值的实体。问问自己,如果查询中的字段值的正确性取决于不在查询中的另一个字段的值,如何验证该字段值。