【问题标题】:Using Java annotations, is there a way to specify Swagger/OpenAPI schemas inside other schemas?使用 Java 注释,有没有办法在其他模式中指定 Swagger/OpenAPI 模式?
【发布时间】:2020-07-16 21:00:39
【问题描述】:

我正在尝试使用 Swagger UI 创建和部署我的文档以及我使用 Spring Boot 编写的 API。我知道 Swagger 提供了一些注释来帮助在实际的控制器类中编写文档,但我在尝试让它们做我需要的事情时遇到了麻烦。

我的问题是我有一个通用 DTO 类,每次调用我的 API 都会返回该类。此 DTO 有一个用于通用对象的 contents 字段。如果我直接使用对象,我知道我可以使用类似的东西

@ApiResponse(responseCode = "200", description = "Customer found",
    content = @Content(
        schema = @Schema(implementation = Customer.class)))

为了给出对象的 JSON 表示应该是什么样子的规范。但是,因为我将所有内容都包装在特定的 ResponseDTO 类中,所以我需要一种方法来指定 contents 字段的外观,我不确定可以使用哪些注释来完成此操作。我觉得肯定应该有类似的东西

@ApiResponse(responseCode = "200", description = "Customer found",
    content = @Content(
        schema = @Schema(implementation = DTO.class, 
                         fields = { "contents" = @Schema(implementation = Customer.class)})))

或类似的东西。我一直无法找到如何真正做到这一点的解释。我的直觉表明应该有一种方法可以将模式放入模式中,但也许还有另一种我没有考虑过的解决方案。任何帮助或寻找方向将不胜感激。提前致谢。

【问题讨论】:

    标签: java spring-boot swagger swagger-ui openapi


    【解决方案1】:

    我知道这篇文章已经过时了,但我还是发布了这篇文章,以防有人遇到类似问题。

    我还必须返回一个对象列表,其中这些对象的字段之一必须根据某些请求参数进行更改。为了在 Swagger 中记录这些子架构(架构内的架构),您可以使用 oneOf attribute@Schema 注释并提供泛型类的列表。

    这是一个例子:

    Customer.java:

    public class Customer {
    
      // Some other fields...
    
      @Schema(
          description = "List of generic contents inside Customer",
          oneOf = {Bar.class, Foo.class})
      private List<IContent> contents;
    
    }
    

    IContent.java 只是一些接口(或者它可以是泛型类的任何类):

    public interface IContent extends Serializable { }
    

    假设Foo.javaBar.java 是您的两个通用 类:

    public class Bar implements IContent {
    
      @Schema(description = "Some dummy name field inside Bar")
      private String dummyName;
    
      @Schema(description = "Some dummy number field inside Bar")
      private Integer dummyNo;
    
    }
    
    public class Foo implements IContent {
    
      @Schema(description = "Some dummy ID field inside Foo")
      private Long contentID;
    
    }
    

    生成的 Swagger UI:

    如果您有与记录通用对象列表不同的需求,请参阅allOf and anyOf attributes 了解其他类型的子模式属性。

    【讨论】:

    • 您使用哪个库将注释转换为 UI? Springfox,springdoc-openapi,还是别的什么?
    • springdoc-openapi v1.5.2
    【解决方案2】:

    我成功地用@Schema 标记了类的字段,它工作正常,但我用它来提供地图信息。

    class CreateReq extends DTO {
    
        @Schema(description="",
            implementation = Products.class)
        Map<String,Map<String,Object>>  products;
    
    }
    
        // For openapi document only
        private static class Products {
            ProductFields productId1;
            ProductFields productId2;
        }
    
        // For openapi document only
        private static class ProductFields {
            String field1;
            Object field2;
    
        }
    

    【讨论】:

      【解决方案3】:

      看起来你是在倒退。为此,我使用 http://swagger.io 的编辑器创建一个指定 API 的 .yaml 文件

      这样,您的 .yaml 文件可以为每种数据类型指定不同的 DTO,并且您可以为每种 API 指定它返回的类型。

      此外,您不会发布您的 ResponseDTO 类的样子。我希望你已经通用了它:

      public class ResponseDTO<T> {
        public T getData() { … }
        …
      }
      

      但我不确定拥有这样的自己的对象是否是个好主意。在我过去的一些项目中,我们为每种数据类型定义了一个单独的响应类,但它们都做同样的事情!您的框架可能已经为您编写了这样的类。

      您正在使用 Spring Boot,这正是我使用的。对于 Spring,类是 org.springframework.http.ResponseEntity。 (其他框架可能有自己的版本。)它是通用的,所以你可以向它添加任何数据类型的内容。但 Swagger 要求您指定添​​加内容的类型,而不是 ResponseEntity 类本身。您的 ResponseDTO 课程妨碍了您。

      所以如果你想返回一个CustomProduct类型,你的swagger生成的注解会指定CustomProduct.class,你的服务方法看起来像这样:

      … (more annotations)
      @ApiResponses(value = { 
        @ApiResponse(code=200, message="Found", response=CustomProduct.class)
      })
      public ResonseEntity<CustomProduct> getCustomProduct(…) {
        CustomProduct myCustomProduct = retrieveCustomProduct(…);
        return new ResponseEntity<>(myCustomProduct, HTTPStatus.OK);
      }
      

      【讨论】:

        猜你喜欢
        • 2022-08-05
        • 2020-04-04
        • 1970-01-01
        • 2019-04-26
        • 2012-01-16
        • 1970-01-01
        • 2021-06-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多