springdoc / springdoc-openapi

Library for OpenAPI 3 with spring-boot

Home Page:https://springdoc.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

feat: Add examples for response automatically

shaunhurryup opened this issue · comments

Background

The interface retrieves detailed information about goods based on their ID and returns one of two responses: either GoodsDto.class or ResourceNotFound.class.

I've defined the interface as follows:

@ApiResponse(
    responseCode = "200",
    content = @Content(
        schema = @Schema(oneOf = {GoodsDto.class, ResourceNotFound.class}),
        mediaType = MediaType.APPLICATION_JSON_VALUE
    )
)
public ResponseEntity<Resp<GoodsDto>> getGoods(@PathVariable("id") String id) {
    return RespUtil.success(Resp.success(new GoodsDto()).build());
}

Below is an example of the HTTP responses for both classes:

ResourceNotFound

@Data
public class ResourceNotFound {
    @Schema(title = "错误码", example = "10001")
    private Integer code;
    @Schema(title = "英文错误信息", example = "Record Not Found")
    private String msg;
    @Schema(title = "中文错误信息", example = "记录未找到")
    private String msg_cn;
    @Schema(title = "其他信息", example = "null")
    private String data;
}
{
  "msg": "Record Not Found",
  "code": 10001,
  "data": "null"
}

GoodsDto

@Data
public class GoodsDto {
    /**
     * 商品ID
     */
    @Schema(title = "商品ID", example = "65669ce3c684f6144ce5cf5f")
    private String id;

    /**
     * 商品名称
     */
    @Schema(title = "商品名称", example = "iPhone 15 Pro Max")
    private String title;

    /**
     * 商品价格
     */
    @Schema(title = "商品价格", example = "9999")
    private int price;

    // ......
}
{
  "msg": "success",
  "code": 0,
  "data": {
    "price": 9999,
    "id": "65669ce3c684f6144ce5cf5f",
    "type": "electronics",
    "title": "iPhone 15 Pro Max",
    "secondHand": false
  }
}

`

Upon starting the service, you can access the OpenAPI document at http://127.0.0.1:8084/api/v3/api-docs?group=SwaggerDemo. Here's a snippet to illustrate

{
  "responses": {
    "200": {
      "description": "OK",
      "content": {
        "application/json": {
          "schema": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/GoodDto"
              },
              {
                "$ref": "#/components/schemas/ResourceNotFound"
              }
            ]
          }
+ Oh! Examples field lacking
        }
      }
    }
  }
}

Problem

The schema is nested under 'application/json', but there's no 'examples' field. My exception looks like the red highlight:

{
  "responses": {
    "200": {
      "description": "OK",
      "content": {
        "application/json": {
          "schema": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/GoodDto"
              },
              {
                "$ref": "#/components/schemas/ResourceNotFound"
              }
            ]
          },
+          "examples": {
+            "ResourceNotFound": {
+              "value": {
+                "msg": "Record Not Found",
+                "code": 10001,
+                "data": "null"
+              }
+            },
+            "GoodDto": {
+              "value": {
+                "code": 0,
+                "msg": "success",
+                "data": {
+                  "shop": null,
+                  "price": 9999,
+                  "description": "这是一款新款 iPhone,性能强劲,拍照效果好,电池续航长",
+                  "id": "65669ce3c684f6144ce5cf5f",
+                  "type": "electronics",
+                  "title": "iPhone 15 Pro Max",
+                  "secondHand": false,
+                  "tags": [
+                    "新款",
+                    "性能强劲",
+                    "拍照效果好",
+                    "电池续航长"
+                  ]
+                }
+              }
+            }
+          }
        }
      }
    }
  }
}

I tried using OpenApiCustomiser to add the example field in the response, but it's too verbose.

Expect

Actually, I've added example definitions for both GoodDto.class and ResourceNotFound.class. Is there a way to automatically add examples according to the schema in the response? As you know, I've already defined it in @ApiResponse :(

@ApiResponse(
    responseCode = "200",
    content = @Content(
        schema = @Schema(oneOf = {GoodDto.class, ResourceNotFound.class}),
        mediaType = MediaType.APPLICATION_JSON_VALUE
    )
)
@Data
public class ResourceNotFound {
    @Schema(title = "错误码", example = "10001")
    private Integer code;
    @Schema(title = "英文错误信息", example = "Record Not Found")
    private String msg;
    @Schema(title = "中文错误信息", example = "记录未找到")
    private String msg_cn;
    @Schema(title = "其他信息", example = "null")
    private String data;
}

@shaunhurryup,

You will have to add examples for each type.
There is no other workarounds.