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

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

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:

  1. 假设我有一个Spring Boot REST API,其中定义了以下端点和模型(为简洁起见,省略了getter/setter
  2. ```java
  3. @JsonTypeInfo(property = "type", include = JsonTypeInfo.As.PROPERTY, use = JsonTypeInfo.Id.NAME)
  4. @JsonSubTypes({@JsonSubTypes.Type(FooWidget.class), @JsonSubTypes.Type(BarWidget.class)})
  5. public interface Widget {}
  6. public class BarWidget implements Widget { private String bar; }
  7. public class FooWidget implements Widget { private String foo; }
  8. public class WidgetGroup {
  9. private List<Widget> widgets;
  10. }
  11. @RestController
  12. public class WidgetController {
  13. @PostMapping("/widgets")
  14. public void createWidgets(@RequestBody WidgetGroup widgets) {
  15. }
  16. }

是否可以在OpenAPI规范中表达这个内容,以便生成器可以同时:

  • 生成上述代码作为服务器存根和模型
  • 生成一个正确表示模型和API的JavaScript客户端

在设置了这一点并尝试使用springdoc和springfox从代码生成规范之后,我无法反转这个过程 - 上述代码通过Springdoc生成了以下规范:

  1. openapi: 3.0.1
  2. info:
  3. title: OpenAPI定义
  4. version: v0
  5. servers:
  6. - url: 'http://localhost:8080'
  7. description: 生成的服务器URL
  8. paths:
  9. /widgets:
  10. post:
  11. tags:
  12. - widget-controller
  13. operationId: createWidgets
  14. requestBody:
  15. content:
  16. application/json:
  17. schema:
  18. $ref: '#/components/schemas/WidgetGroup'
  19. required: true
  20. responses:
  21. '200':
  22. description: OK
  23. components:
  24. schemas:
  25. BarWidget:
  26. type: object
  27. allOf:
  28. - $ref: '#/components/schemas/Widget'
  29. - type: object
  30. properties:
  31. bar:
  32. type: string
  33. FooWidget:
  34. type: object
  35. allOf:
  36. - $ref: '#/components/schemas/Widget'
  37. - type: object
  38. properties:
  39. foo:
  40. type: string
  41. Widget:
  42. required:
  43. - type
  44. type: object
  45. properties:
  46. type:
  47. type: string
  48. discriminator:
  49. propertyName: type
  50. WidgetGroup:
  51. type: object
  52. properties:
  53. widgets:
  54. type: array
  55. items:
  56. oneOf:
  57. - $ref: '#/components/schemas/BarWidget'
  58. - $ref: '#/components/schemas/FooWidget'

当使用Java和JavaScript生成器时,继承信息似乎丢失了,会生成奇怪的类,比如"BarWidgetAllOf"。这是OAS规范表达能力的局限性,还是生成器实现的限制(我尝试过swagger-codegen和openapitools生成器)?

  1. <details>
  2. <summary>英文:</summary>
  3. 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 )
{
}
}

  1. Is it possible to express this in an OpenAPI spec so that a generator could both
  2. * reproduce the above code as server stubs and models
  3. * produce a Javascript client which correctly represented the models and API
  4. 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'
  1. 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)?
  2. </details>
  3. # 答案1
  4. **得分**: 0
  5. The generated OpenAPI spec is correct regarding your code.
  6. This is not a limitation, but there needs to be default generation which is commonly used.
  7. 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:
  8. - [Link to the first issue](https://github.com/swagger-api/swagger-core/issues/3046)
  9. <details>
  10. <summary>英文:</summary>
  11. The generated OpenAPI spec is correct regarding your code.
  12. This is not a limitation, but there needs to be default generation which is commonly used.
  13. 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:
  14. - https://github.com/swagger-api/swagger-core/issues/3046
  15. </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:

确定