如何在从Java代码生成的Swagger规范中创建可重用的枚举?

时间:2019-07-17 15:48:11

标签: java swagger

我正在尝试为我的Java代码生成OpenAPI(版本3.0.1)规范。为了实现此目的,我使用了Swagger注释(2.0.8版)和Swagger Maven插件。

我对枚举有疑问。说,我有两种方法返回相同的Enum。在OpenAPI规范中,我希望在两个API操作中都具有此Enum和import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; @Path("/properties") @Produces("application/json") public class TestService { @GET @Path("/enum1") @Operation @ApiResponses({ @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Color.class))) }) public Color getColor1() { throw new UnsupportedOperationException(); } @GET @Path("/enum2") @Operation @ApiResponses({ @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Color.class))) }) public Color getColor2() { throw new UnsupportedOperationException(); } public enum Color { RED, GREEN, BLUE } } 链接的单一架构定义。但是相反,我在每个API操作中都重复了Enum定义。在不手动编辑规范文件的情况下如何避免重复?

这是Java代码,其中有两个方法返回相同的Enum:

openapi: 3.0.1
components:
    schemas:
        Color:
            type: string
            enum:
                - RED
                - GREEN
                - BLUE
paths:
  /properties/enum2:
    get:
      operationId: getColor2
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Color'
  /properties/enum1:
    get:
      operationId: getColor1
      responses:
        200:
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Color'

这是我想要得到的规范

openapi: 3.0.1
paths:
  /properties/enum2:
    get:
      operationId: getColor2
      responses:
        200:
          content:
            application/json:
              schema:
                type: string
                enum:
                - RED
                - GREEN
                - BLUE
  /properties/enum1:
    get:
      operationId: getColor1
      responses:
        200:
          content:
            application/json:
              schema:
                type: string
                enum:
                - RED
                - GREEN
                - BLUE

这是我得到的规范:

ObjectID | Column1
1        | 152
1        | 154
1        | 157
1        | 158
2        | 101
2        | 154
2        | 155
3        | 3
3        | 97
3        | 98
3        | 99

2 个答案:

答案 0 :(得分:2)

我在 kotlin 中,但我成功地将(相对较新的)@Schema(enumAsRef = true) 添加到枚举类中。

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path("/properties")
@Produces("application/json")
public class TestService {
    @GET
    @Path("/enum1")
    @Operation
    @ApiResponses({
        @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Color.class)))
    })
    public Color getColor1() {
        throw new UnsupportedOperationException();
    }

    @GET
    @Path("/enum2")
    @Operation
    @ApiResponses({
        @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Color.class)))
    })
    public Color getColor2() {
        throw new UnsupportedOperationException();
    }

    @Schema(enumAsRef = true) // THIS MAKES ENUM REF
    public enum Color {
        RED,

        GREEN,

        BLUE
    }
}

答案 1 :(得分:0)

我在使用 Dropwizard 应用程序时遇到了同样的问题。

我的模型是这样的:

public class Model {

  @Schema(name = "fields")
  @Default
  @NotNull
  private Set<CustomEnum> fields = Collections.emptySet();

  @Schema(name = "patches")
  @Default
  @NotNull
  private Set<CustomEnum> patches = Collections.emptySet();
}

和我的枚举:

public enum CustomEnum {
  COMPANY,
  PERSON,
  EMAIL
}

我的方法如下:

首先,将 @Schema 注释添加到 CustomEnum 枚举:

@Schema(ref = "#/components/schemas/CustomEnumItem")
public enum CustomEnum {}

请注意,我将引用名称更改为 CustomEnumItem

其次,我以编程方式注册了架构和 swagger 配置:

OpenAPI oas =
    new OpenAPI()
        .info(getInfo())
        .addServersItem(new Server().url(baseUrl));

var customEnumItem = new Schema<CustomEnumItem>();
patchKeysItem.setType("string");
patchKeysItem.setEnum(List.of(CustomEnumItem.values()));
oas.getComponents().addSchemas("CustomEnumItem", customEnumItem);

return new SwaggerConfiguration()
    .openAPI(oas)
    .readAllResources(true)
    .prettyPrint(true);

所以,我的 swagger.json 文件是这样生成的:

  • 架构部分:
  "components" : {
    "schemas" : {
      "PatchKeyItem" : {
        "type" : "string",
        "enum" : [ "COMPANY", "PERSON", "EMAIL"]
      },
  • 模型部分:
"Model" : {
        "required" : [ "fields", "patches"],
        "type" : "object",
        "properties" : {
          "fields" : {
            "uniqueItems" : true,
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/CustomEnumItem"
            }
          },
          "patches" : {
            "uniqueItems" : true,
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/CustomEnumItem"
            }
          },

我生成的客户端代码如下:

public class Model  {

    @JsonProperty("fields")
    private Set<CustomEnumItem> fields;

    @JsonProperty("patches")
    private Set<CustomEnumItem> patches;

在此更改之前,我得到了类似的信息(两个枚举而不是一个):

public class Model  {

    @JsonProperty("fields")
    private Set<FieldsEnum> fields;

    @JsonProperty("patches")
    private Set<PatchesEnum> patches;
}

我们可以找到对可重用枚举 here 的引用。

正如@david-karlsson 提到的,enumAsRef 也可以使用,但您需要 2.1.0 的 swagger 注释。