Java 接口作为 DTO 字段的 OpenAPI 示例

Java OpenAPI example for interface as a DTO field

我在 Spring 中有应用程序,并在 OpenAPI 中为此创建了文档,其中包含控制器方法的注释。例如,我有方法 getById (为了便于阅读而简化):

@GetMapping("/{id}")
@ApiResponse(
    responseCode = "200", 
    description = "Successful operation.",
    content = @Content(
            mediaType = "application/json", 
            schema = @Schema(implementation = ScheduleResponse.class)
    )
)
@ApiResponse(
    responseCode = "404", 
    description = "The object with the specified ID does not exist in the system.",
    content = @Content(
            mediaType = "application/json", 
            schema = @Schema(implementation = ApiError.class)
    )
)
ScheduleResponse getById(@PathVariable Long id) throws EntityNotFoundException;

对于 404 NOT_FOUND 我 returns 我自己的 ApiError 列表 ApiErrorDetails 接口:

@Getter
public class ApiError {

    private final LocalDateTime timestamp;
    private final String status;
    private final String message;
    private List < ApiErrorDetails > details;
}

public interface ApiErrorDetails {
}

在那种情况下,我正在使用接口的特定实现:

@Getter
public class EntityNotFoundDetails implements ApiErrorDetails {

    private final String field;
    private final Object notFoundValue;
}

通过上述实现,我在文档中得到 JSON,details 中没有特定的字段信息,例如:

和模式:

相反,我想准备一个这样的例子:

{
  "timestamp": "2021-08-08T13:32:10.875Z",
  "status": "string",
  "message": "string",
  "details": [
    {
      "field": "string",
      "notFoundValue": {}
    }
  ]
}

当然,我需要针对特定​​情况的解决方案。这意味着我不想添加

@Schema(example = "value")

details列表,因为我在不同情况下提供不同的实现。

我找到了一个不完美但足以用于文档目的的解决方案。

所需要做的就是在 ApiErrorDetails 上添加 @Schema 注释和 属性 oneOf。例如对于两个接口实现:EntityNotFoundDetailsValidationErrorDetails:

@Schema(oneOf = {EntityNotFoundDetails.class, ValidationErrorDetails.class})
interface ApiErrorDetails {
}

在文档中,它看起来像这样:

这表明 JSON 的形状与实际略有不同,但模式选项卡消除了疑虑:

可能提供您选择的一种实现的唯一方法是简单地使用不同的 类 而不是扩展接口。