英文:
How can I generate an openapi definition which supports a polymorphic request body, and can generate client and server stubs accordingly?
问题
Here's the translated content you provided:
假设我有一个Spring Boot REST API,其中定义了以下端点和模型(为简洁起见,省略了getter/setter)
```java
@JsonTypeInfo(property = "type", include = JsonTypeInfo.As.PROPERTY, use = JsonTypeInfo.Id.NAME)
@JsonSubTypes({@JsonSubTypes.Type(FooWidget.class), @JsonSubTypes.Type(BarWidget.class)})
public interface Widget {}
public class BarWidget implements Widget { private String bar; }
public class FooWidget implements Widget { private String foo; }
public class WidgetGroup {
private List<Widget> widgets;
}
@RestController
public class WidgetController {
@PostMapping("/widgets")
public void createWidgets(@RequestBody WidgetGroup widgets) {
}
}
是否可以在OpenAPI规范中表达这个内容,以便生成器可以同时:
- 生成上述代码作为服务器存根和模型
- 生成一个正确表示模型和API的JavaScript客户端
在设置了这一点并尝试使用springdoc和springfox从代码生成规范之后,我无法反转这个过程 - 上述代码通过Springdoc生成了以下规范:
openapi: 3.0.1
info:
title: OpenAPI定义
version: v0
servers:
- url: 'http://localhost:8080'
description: 生成的服务器URL
paths:
/widgets:
post:
tags:
- widget-controller
operationId: createWidgets
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/WidgetGroup'
required: true
responses:
'200':
description: OK
components:
schemas:
BarWidget:
type: object
allOf:
- $ref: '#/components/schemas/Widget'
- type: object
properties:
bar:
type: string
FooWidget:
type: object
allOf:
- $ref: '#/components/schemas/Widget'
- type: object
properties:
foo:
type: string
Widget:
required:
- type
type: object
properties:
type:
type: string
discriminator:
propertyName: type
WidgetGroup:
type: object
properties:
widgets:
type: array
items:
oneOf:
- $ref: '#/components/schemas/BarWidget'
- $ref: '#/components/schemas/FooWidget'
当使用Java和JavaScript生成器时,继承信息似乎丢失了,会生成奇怪的类,比如"BarWidgetAllOf"。这是OAS规范表达能力的局限性,还是生成器实现的限制(我尝试过swagger-codegen和openapitools生成器)?
<details>
<summary>英文:</summary>
Let's say I have a Spring Boot REST API with the following endpoint and models defined (getters/setters omitted for brevity)
@JsonTypeInfo( property = "type", include = JsonTypeInfo.As.PROPERTY, use = JsonTypeInfo.Id.NAME )
@JsonSubTypes( { @JsonSubTypes.Type( FooWidget.class ), @JsonSubTypes.Type( BarWidget.class ) } )
public interface Widget {}
public class BarWidget implements Widget { private String bar; }
public class FooWidget implements Widget { private String foo; }
public class WidgetGroup
{
private List<Widget> widgets;
}
@RestController
public class WidgetController
{
@PostMapping( "/widgets" )
public void createWidgets( @RequestBody WidgetGroup widgets )
{
}
}
Is it possible to express this in an OpenAPI spec so that a generator could both
* reproduce the above code as server stubs and models
* produce a Javascript client which correctly represented the models and API
Having set this up and tried both springdoc and springfox to generate me a spec from the code, I've then not been able to reverse the process - the above code generates the following spec via Springdoc:
openapi: 3.0.1
info:
title: OpenAPI definition
version: v0
servers:
- url: 'http://localhost:8080'
description: Generated server url
paths:
/widgets:
post:
tags:
- widget-controller
operationId: createWidgets
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/WidgetGroup'
required: true
responses:
'200':
description: OK
components:
schemas:
BarWidget:
type: object
allOf:
- $ref: '#/components/schemas/Widget'
- type: object
properties:
bar:
type: string
FooWidget:
type: object
allOf:
- $ref: '#/components/schemas/Widget'
- type: object
properties:
foo:
type: string
Widget:
required:
- type
type: object
properties:
type:
type: string
discriminator:
propertyName: type
WidgetGroup:
type: object
properties:
widgets:
type: array
items:
oneOf:
- $ref: '#/components/schemas/BarWidget'
- $ref: '#/components/schemas/FooWidget'
When using both Java and Javascript generators, the inheritance information seems to get lost and odd classes like "BarWidgetAllOf" get generated. Is this a limitation in the expressiveness of the OAS spec, or just a limitation in the implementations of the generators (I have tried both with the swagger-codegen and openapitools generators)?
</details>
# 答案1
**得分**: 0
The generated OpenAPI spec is correct regarding your code.
This is not a limitation, but there needs to be default generation which is commonly used.
If you want finer control of the generated spec, you can use the swagger @Schema annotation (without using JsonSubTypes), as explained in these two issues with examples:
- [Link to the first issue](https://github.com/swagger-api/swagger-core/issues/3046)
<details>
<summary>英文:</summary>
The generated OpenAPI spec is correct regarding your code.
This is not a limitation, but there needs to be default generation which is commonly used.
If you want finer control of the generated spec, you can swagger @Schema annotation (without using JsonSubTypes), as explained in this two issues with examples:
- https://github.com/swagger-api/swagger-core/issues/3046
</details>
专注分享java语言的经验与见解,让所有开发者获益!
评论