How can I generate an openapi definition which supports a polymorphic request body, and can generate client and server stubs accordingly?

huangapple 未分类评论72阅读模式
英文:

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&#39;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&#39;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 &quot;BarWidgetAllOf&quot; 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>



huangapple
  • 本文由 发表于 2020年8月14日 19:09:13
  • 转载请务必保留本文链接:https://java.coder-hub.com/63411617.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定