【问题标题】:springdoc-openapi spec generation for inheritance witth generics使用泛型继承的springdoc-openapi规范生成
【发布时间】: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

这里的问题是我的控制器可以返回DogFoodCatFood,这是在返回类型中指定的。我希望生成的架构是:

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

有什么方法可以实现吗?

【问题讨论】:

    标签: swagger openapi springfox springdoc


    【解决方案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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-14
      • 1970-01-01
      • 1970-01-01
      • 2022-10-13
      • 2020-04-02
      • 2020-06-14
      • 1970-01-01
      • 2020-08-24
      相关资源
      最近更新 更多