在使用 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 生态系统中,我如何才能以一种好的方式实现这一点,考虑到这里最相关的库需要对它有全面的支持:
- Jackson(JSON反序列化)
- Hibernate 验证器(Bean 验证)
- Microprofile OpenAPI(API 定义)
Java 可选
除此以外,我尝试了 Java-Optional,虽然它最初似乎可行,但它却是错误的工具,因为 Optional 不应该包含 NULL 值,但也应该能够在 PATCH 中明确将值设置为 NULL(而不是省略它)。
- 但我确实在使用 Optional 方面取得了很大进展。唯一的问题是 Hibernate Validator 没有以我需要的方式支持它。
例如,以下内容最初看起来不错(此处的名称字段为 required = false 和 nullable = false):
@Schema(required = false, nullable = false)
Optional<@NotNull @Size(max = 255) String> name = Optional.empty();
当请求中缺少名称字段时,Hibernate 验证器认为 @NotNull 注释被违反,我发现这很奇怪,因为注释位于 Optional-Generic-Declaration 内(而不是直接在 Optional 上)
JsonNullable
Jackson 提供了 JsonNullable 注释。虽然这是完成任务的正确工具,并且似乎支持 openapi,但它似乎不支持 hibernate 验证器,至少我找不到有关它的信息。
验证
大部分问题似乎发生在 Bean 验证注释的验证过程中,这对于 API 来说很重要。
- 当使用诸如等注释时,
@Size(255)
有@Email
以下要求......- ...当在 PATCH 中给出/设置字段时,这些验证必须由 Hibernate Validator 进行验证
- ...当 PATCH 中省略(缺失)该字段时,不得验证这些验证。
--
REST-PATCH 是否包含在 Java 生态系统的那些主要库中?如果是,建议以何种方式来支持它?
如何在请求体中获取键值映射,其中键与字段名称匹配。
那么字段值为空的情况将不会与请求中不存在该字段的情况重叠,并且您可以使用 ObjectMapper 自动仅更新请求中出现的那些字段。
当然,您无法从请求中验证字段值,但您会自动验证使用这些值更新字段的实体。问问自己,如果字段值的正确性取决于请求中没有的另一个字段的值,您如何从请求中验证字段值。
基于 Andrey Smeliks 的方法,我发现了一些额外的调整,让我能够以我认为可以的方式基于这种方法使用 OpenAPI 和 Hibernate Validator。
控制器
服务/经理