生成 Spring 代码时如何将 OpenAPI“oneOf”属性与 openapi-generator-maven-plugin 一起使用
Posted
技术标签:
【中文标题】生成 Spring 代码时如何将 OpenAPI“oneOf”属性与 openapi-generator-maven-plugin 一起使用【英文标题】:How to use OpenAPI "oneOf" property with openapi-generator-maven-plugin when generating Spring code 【发布时间】:2020-10-26 19:40:03 【问题描述】:我正在开发一个带有 Angular 前端和 RESTful Spring Boot 后端的应用程序
我从 org.openapitools 找到了这个非常方便的 maven 插件 openapi-generator-maven-plugin。凭借其代码生成功能,它有助于在我们的 API 的前端和后端之间实施“合同优先”的方法。但是我们的 swagger 文件在 requestBody 和 responseBody 定义中使用了“oneOf”属性。我试图从中生成 Spring 代码,但生成的 Java 类缺少导入:
import com.pack.api.dto.OneOfLatteCoffeAmericanoCoffe;
import com.pack.api.dto.UNKNOWN_BASE_TYPE;
是否可以将插件与 Swagger 的 oneOf 属性一起使用?我正在使用 Spring Boot 2.3.1、Swagger 3.0 和 Openapi-generator-maven-plugin 4.3
【问题讨论】:
【参考方案1】:目前,openapi-generator 不支持oneOf
。这是 OpenAPI v3 新引入的功能(仅供参考,只有 v2 及以下版本称为“Swagger”,然后已重命名为 OpenAPI)。有各种生成器(Java、Spring、许多其他语言)。我在今年看到contributions have been made 到enable oneOf
support。
总而言之,在您可以使用 Spring 生成器利用 OpenAPI v3 规范的这一特性之前,您似乎需要再等一会儿。
编辑:它也列出了on the "short term roadmap":
OAS3.0 功能支持:anyOf、oneOf、回调等
【讨论】:
我一直在努力为大量使用 anyOf 和 oneOf 的 API 生成 php 客户端。经过一些谷歌搜索并发现围绕这个主题的堆栈溢出问题令人惊讶地很少,我猜对多态性的支持真的是代码生成的一个强大的 WIP 主题? 刚刚也遇到了这个问题:(【参考方案2】:如果您可以修改您的招摇,您可以将oneOf
替换为对抽象类型的引用。
例如,如果你的招摇看起来像这样:
components:
schemas:
'Parent':
'vehicle':
oneOf:
- type: object
properties:
'car_property':
type: string
- type: object
properties:
'truck_property':
type: string
你可以这样修改:
components:
schemas:
'Parent':
type: object
properties:
'vehicle':
$ref: '#/components/schemas/Vehicle'
#---------------------------------------------------------------------------
# Abstract class with discriminator 'vehicle_type'
#---------------------------------------------------------------------------
'Vehicle':
type: object
properties:
'vehicle_type':
type: string
enum: [ 'CAR', 'TRUCK' ]
discriminator:
propertyName: vehicle_type
mapping:
'CAR': '#/components/schemas/Car'
'TRUCK': '#/components/schemas/Truck'
#---------------------------------------------------------------------------
# Concrete classes
#---------------------------------------------------------------------------
'Car':
allOf:
- $ref: "#/components/schemas/Vehicle"
- type: object
properties:
'car_property':
type: string
'Truck':
allOf:
- $ref: "#/components/schemas/Vehicle"
- type: object
properties:
'truck_property':
type: string
这种大摇大摆的修改使生成器工作。它处理相同的 JSON 对象,尽管我不能 100% 确定它在 OpenAPI 规范中的语义等价。
【讨论】:
在尝试此解决方案时,我仍然在抽象模型中得到:@JsonSubTypes( @JsonSubTypes.Type(value = ERRORUNKNOWN.class, name = "Obj1"), @JsonSubTypes.Type(value = ERRORUNKNOWN.class, name = "Obj2"), )
,编译失败。【参考方案3】:
我们为java
(jersey2)、csharp-netcore
等一些生成器添加了更好的 oneOf 和 anyOf 支持。请用最新的大师试一试。 SNAPSHOT 版本可以在项目的 README 中找到:https://github.com/OpenAPITools/openapi-generator/
【讨论】:
maven available 5.1.1 不支持 oneof 和 anyof 代码生成。 5.2.0-SNAPSHOT 和 6.0.0-SNAPSHOT 在 maven 上不可用。如果这两个版本支持其中一个,你建议如何尝试?必须在生产代码中使用此实用程序。【参考方案4】:对我来说,创建的 csharp 生成的模型对象不正确。 它会生成以下内容,
[DataMember(Name = "category", IsRequired = true, EmitDefaultValue = true)]
public OneOfobjectobjectobject Category get; set;
它创建一个以单词 Oneof 开头的对象并附加三个对象,因为我的 openapi 规范文档中有三个 oneOfs 用于类别。 有没有办法返回字典或其他东西?上面的代码无法编译。 我的类别的 openapi 架构如下
category:
title: Category
oneOf:
- title: Year
type: object
properties:
type:
title: Type
enum:
- year
type: string
additionalProperties: false
required:
- type
- title: Term
type: object
properties:
type:
title: Type
enum:
- term
type: string
parent:
title: Parent
oneOf:
- title: Academic Period
type: object
properties:
academicPeriod:
title: Academic Period
type: object
properties:
id:
title: ID
description: The global identifier for the Academic Period.
type: string
format: guid
pattern: ^[a-f0-9]8(?:-[a-f0-9]4)3-[a-f0-9]12$
additionalProperties: false
required:
- id
additionalProperties: false
required:
- academicPeriod
- title: Academic Year
type: object
properties:
academicYear:
title: Academic Year
type: number
additionalProperties: false
required:
- academicYear
preceding:
title: Preceding
oneOf:
- type: object
properties:
id:
title: ID
description: The global identifier for the Preceding.
type: string
format: guid
pattern: ^[a-f0-9]8(?:-[a-f0-9]4)3-[a-f0-9]12$
additionalProperties: false
required:
- id
- type: object
maxProperties: 0
additionalProperties: false
required:
- type
- title: Subterm
type: object
properties:
type:
title: Type
enum:
- subterm
type: string
parent:
title: Parent
type: object
properties:
id:
title: ID
description: The global identifier for the Parent.
type: string
format: guid
pattern: ^[a-f0-9]8(?:-[a-f0-9]4)3-[a-f0-9]12$
additionalProperties: false
required:
- id
preceding:
title: Preceding
oneOf:
- type: object
properties:
id:
title: ID
description: The global identifier for the Preceding.
type: string
format: guid
pattern: ^[a-f0-9]8(?:-[a-f0-9]4)3-[a-f0-9]12$
additionalProperties: false
required:
- id
- type: object
maxProperties: 0
sectionDateOverride:
title: Section Date Override
oneOf:
- type: string
enum:
- notAllowed
- type: string
maxLength: 0
additionalProperties: false
required:
- type
- parent
【讨论】:
以上是关于生成 Spring 代码时如何将 OpenAPI“oneOf”属性与 openapi-generator-maven-plugin 一起使用的主要内容,如果未能解决你的问题,请参考以下文章
在 Spring Boot 中自动生成 API 文档 [关闭]
在 Spring Boot 中使用 Gradle 从 Swagger OpenAPI 生成 RestClient 存根
使用 springdoc-openapi 和 spring-boot-starter-data-mongodb 生成 OpenAPI 文档
如何从 openapi 生成器编译一个在生成的源文件夹中实现接口的项目?