使用泛型继承的springdoc-openapi规范生成
Posted
技术标签:
【中文标题】使用泛型继承的springdoc-openapi规范生成【英文标题】:springdoc-openapi spec generation for inheritance witth generics 【发布时间】:2020-04-21 19:03:47 【问题描述】:我有一个 Spring Boot (kotlin) 项目,我使用 springdoc-openapi 生成 OpenApi 3 规范。我的数据模型如下所示:
open class Animal
data class Cat(val catName: String) : Animal()
data class Dog(val dogName: String) : Animal()
open class Food<T : Animal>
class CatFood : Food<Cat>()
class DogFood : Food<Dog>()
还有一个像这样的简单控制器:
@GetMapping("/test")
fun test(): Food<out Animal> = DogFood()
为其生成的yaml是:
openapi: 3.0.1
info:
title: OpenAPI definition
version: v0
servers:
- url: http://localhost:8085
paths:
/test:
get:
tags:
- test-controller
operationId: test
responses:
"200":
description: default response
content:
'*/*':
schema:
$ref: '#/components/schemas/FoodAnimal'
components:
schemas:
FoodAnimal:
type: object
这里的问题是我的控制器可以返回DogFood
或CatFood
,这是在返回类型中指定的。我希望生成的架构是:
openapi: 3.0.1
info:
title: OpenAPI definition
version: v0
servers:
- url: http://localhost:8085
paths:
/test:
get:
tags:
- test-controller
operationId: test
responses:
"200":
description: default response
content:
'*/*':
schema:
oneOf:
- $ref: '#/components/schemas/FoodAnimal'
- $ref: '#/components/schemas/DogFood'
- $ref: '#/components/schemas/CatFood'
components:
schemas:
FoodAnimal:
type: object
CatFood:
allOf:
- $ref: '#/components/schemas/FoodAnimal'
type: object
DogFood:
allOf:
- $ref: '#/components/schemas/FoodAnimal'
type: object
有什么方法可以实现吗?
【问题讨论】:
【参考方案1】:对于继承,你只需要在你的父类上添加@Schema注解:
@Schema(
type = "object",
title = "Food",
subTypes = [CatFood::class, DogFood::class]
)
open class Food<T : Animal>
class CatFood : Food<Cat>()
class DogFood : Food<Dog>()
如果您需要使用 oneOf 进行响应,则必须添加 @Response:
@GetMapping("/test")
@ApiResponse(content = [Content(mediaType = "*/*", schema = Schema(oneOf = [Food::class, CatFood::class,DogFood::class]))])
fun test(): Food<out Animal> = DogFood()
【讨论】:
这似乎不允许属性继承【参考方案2】:我在使用带有嵌套属性继承的 OpenApi 时遇到了问题。
我使用 JsonSubtype 注释和泛型作为解决方法。
data class AnimalResponse<FoodResponse>(
val id: UUID,
val eats: FoodResponse
)
@JsonSubTypes(value = [
JsonSubTypes.Type(
value = CatFoodResponse::class,
name = "CAT_FOOD"
), JsonSubTypes.Type(
value = DogFoodResponse::class,
name = "DOG_FOOD"
)])
interface FoodResponse
这将在 AnimalResponse Schema 中显示所有类型的 FoodResponse。
【讨论】:
以上是关于使用泛型继承的springdoc-openapi规范生成的主要内容,如果未能解决你的问题,请参考以下文章
springdoc-openapi 应用默认全局 SecurityScheme 可能吗?
springdoc-openapi swagger-ui 中的 CSRF 支持
使用 springdoc-openapi 和 spring-boot-starter-data-mongodb 生成 OpenAPI 文档