こんにちは、エキサイト株式会社の平石です。
こちらの記事で、Spring BootからOpenAPIのドキュメントを自動生成する方法について説明されています。
しかし、APIのレスポンスにListまたは配列の項目が存在していた場合に、アノテーションでの情報の補完に少し躓きました。
そこで今回は、Listまたは配列の項目が存在する場合のアノテーションの記述方法について紹介します。
今回扱う例
以下のようなコードからOpenAPIのドキュメントを自動生成することを考えます。
@RestController @RequestMapping("example") public class ExampleController { @GetMapping public ExampleResponse getResponse() { final ExampleResponse response = new ExampleResponse(); response.setStringField("Hello, excite!"); response.setArrayField(List.of("東京", "大阪", "福岡")); return response; } }
@Data public class ExampleResponse { private String stringField; private List<String> arrayField; }
そのままアノテーションを付与して情報を補完すると、以下のようになるかと思います。 (ステータス500が返る場合については省略しています。)
@RestController @RequestMapping("example") @Tag(name = "example") public class ExampleController { @GetMapping @Operation(summary = "example") @ApiResponses(value = { @ApiResponse( responseCode = "200", description = "正常に処理が終了した場合", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExampleResponse.class)) ) }) public ExampleResponse getResponse() { final ExampleResponse response = new ExampleResponse(); response.setStringField("Hello, excite!"); response.setArrayField(List.of("東京", "大阪", "福岡")); return response; } }
@Data @Schema(title = "サンプルのレスポンス") public class ExampleResponse { @Schema(type = "string", title = "文字列のフィールド", example = "文字列", requiredMode = Schema.RequiredMode.REQUIRED) private String stringField; @Schema(type = "array", title = "arrayのフィールド", example = "[\"東京\",\"大阪\",\"福岡\"]", requiredMode = Schema.RequiredMode.REQUIRED) private List<String> arrayField; }
このような記述からドキュメントを生成すると、以下のようなyamlのドキュメントができ上がります。
openapi: 3.0.1 info: title: API document of app api description: API document of app api version: 1.0.0 servers: - url: http://localhost:8184 description: URL in local paths: /example: get: tags: - example summary: example operationId: getResponse responses: "200": description: 正常に処理が終了した場合 content: application/json: schema: $ref: '#/components/schemas/ExampleResponse' components: schemas: ExampleResponse: title: サンプルのレスポンス required: - arrayField - stringField type: object properties: stringField: title: 文字列のフィールド type: string example: 文字列 arrayField: title: arrayのフィールド type: array example: - 東京 - 大阪 - 福岡 items: title: arrayのフィールド type: string example: "[\"東京\",\"大阪\",\"福岡\"]"
大体はうまく生成できているのですが、arrayField
のitems
の部分が少し違和感のある結果になっています。
title
がarrayのフィールド
のままになっていますし、example
も不正確です。(本当は、「東京」や「大阪」が入ってほしいはず)
では、どうするか
結論から言いますと、@ArraySchema
を使います。
そして、この@ArraySchema
内の属性arraySchema
で配列やリスト自体の記述をし、schema
属性で配列やリスト内の各要素に関する記述をします。
具体的には、
@Data @Schema(title = "サンプルのレスポンス") public class ExampleResponse { @Schema(type = "string", title = "文字列のフィールド", example = "文字列", requiredMode = Schema.RequiredMode.REQUIRED) private String stringField; @ArraySchema( arraySchema = @Schema( type = "array", title = "arrayのフィールド", example = "[\"東京\",\"大阪\",\"福岡\"]", requiredMode = Schema.RequiredMode.REQUIRED ), schema = @Schema( type = "string", title = "arrayの中身", example = "東京" ) ) private List<String> arrayField; }
のように記述します。
この記述の状態でyamlファイルを生成すると...
components: schemas: ExampleResponse: title: サンプルのレスポンス required: - stringField type: object properties: stringField: title: 文字列のフィールド type: string example: 文字列 arrayField: title: arrayのフィールド type: array example: - 東京 - 大阪 - 福岡 items: title: arrayの中身 type: string example: 東京
このように、items
の下についても生成を制御することができます。
ちなみに、この@ArraySchema
では、最大(小)要素数や、要素がユニークかどうかのような設定も可能なようです。
StringやIntegerの配列やListを扱うときには、使用することを検討してもいいのではないでしょうか。
終わりに
今回は、Listまたは配列の項目が存在する場合のアノテーションの記述方法について紹介しました。
では、また次回。