こんにちは、エキサイト株式会社の平石です。
今回は、SpringdocでAPIのリクエストに対して、付与するアノテーションをご紹介します。
なお、今回のソースコードは以下の環境で動作確認をしています。
'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0'
- Java 21
- SpringBoot 3.2.2
はじめに
SpringdocはOpenAPI仕様のAPIドキュメントを自動で生成してくれるライブラリです。
ドキュメントを書く手間も省けますし、Swagger UIを利用すればAPIの動作確認もできるので、事業部でも積極的に活用しています。
Springdocでは、Controllerを記述するだけで最低限のドキュメントを作成してくるのですが、ライブラリで提供される専用のアノテーションを付与することで、情報を補足することもできます。
特に、Controllerを書くだけでは「どのような動作をするAPIなのかの説明」「それぞれのパラメータやレスポンスの詳細な説明」といった情報は表示されませんので、アノテーションを利用して補足する必要があります。
例えば、以下のようなControllerを作成したとします。
@RestController @RequestMapping("sample") @Tag(name = "sample") public class SampleController { @GetMapping @Operation(summary = "サンプルのAPI") @ApiResponses(value = { @ApiResponse( responseCode = "201", description = "正常に処理が終了した場合" ), @ApiResponse( responseCode = "500", description = "API内部でエラーが発生した場合" ) }) public String sample() { return "Hello, Excite"; } }
この時、Swagger UIを確認すると以下のように反映されています。
サンプルのAPI
や正常に処理が終了した場合
といった文言はアノテーションで補足しないと反映されない内容です。
@Schemaを乱用して発生した問題
これまで、私の所属するチームではSpringdocでAPIの情報を補足する際に、リクエストにもレスポンスにも@Schema
のみを付与していました。
@Schema
はOpenAPI仕様上でデータモデルを定義するために使われるアノテーションです。
データモデルと言いつつも、単一のフィールドやパラメータを表現するのにも使用することができます。
しかし、@Schema
単体ではリクエストの際に適切に型が反映されないという問題がありました。
例えば、以下のようなControllerを考えます。
@RestController @RequestMapping("sample") @Tag("sample") public class SampleController { @GetMapping public String sample( @ParameterObject SampleRequestDto requestDto ) { return "Hello, Excite!"; } }
SampleResponseDtoには、これから様々なフィールドを記述していきます。
リクエストの場合
APIのリクエストは、Controller内のメソッドの引数にString
やInteger
の状態で直接渡すこともできますし、全てのパラメータをまとめたDTOを渡すこともできます。
今回は、DTOを作成してみます。
Javaのレコード・クラスを利用すると便利です。
public record SampleRequestDto(
String stringField,
Integer integerField,
Long longField
) {
}
この状態でSwagger UIを確認してみます。
各パラメータが認識され、型もJava側で宣言した型からOpenAPI仕様で定義されている型に自動で変換してくれています。
ちなみに、()内に$マークと一緒に記述されているint32
やdate-time
はformat
です。
integer($int64)
はinteger
というtype(型)の$int64
というフォーマットであることを表しています。
int64
はLong型のことなので、Javaの型がOpenAPI仕様で利用できる適切な型(+ フォーマット)に自動的に変換されていることがわかります。
では、リクエストに、description
やexample
を記述して情報を補足してみます。
public record SampleRequestDto( @Schema(description = "文字列のパラメータ", example = "文字列") String stringField, @Schema(description = "Integer型のパラメータ", example = "1") Integer integerField, @Schema(description = "Long型のパラメータ", example = "2") Long longField ) { }
Swagger UIを確認してみます。
おや?確かに、Description
でコメントによる補足は反映されていますが、型が全てstring
になってしまっています。
Springdocではリクエストパラメータでは@Schema
で補足情報を加えようとすると、型を自動で変換することができず全てstring
になってしまうようです。
この仕様が謎であったため、公式ドキュメントを眺めているとリクエストパラメータの時には@Parameter
というアノテーションを利用すると良いようです。
@Parameter
でもdescription
やexample
をそのまま指定することが出来ます。
public record SampleRequestDto( @Parameter(description = "文字列のパラメータ", example = "文字列") String stringField, @Parameter(description = "Integer型のパラメータ", example = "1") Integer integerField, @Parameter(description = "Long型のパラメータ", example = "2") Long longField ) { }
Swagger UIを確認してみます。
今度は、型が反映されています。
@Parameter
ではパラメータを入れる場所(ヘッダやクエリパラメータ等)を指定するin
、空の値を許可するかどうかを示すallowEmptyValue
などのように、リクエストパラメータに特化した属性値をセットすることもできるため、今後はこちらを利用していきたいと思います。
おわりに
今回は、Springdocでアノテーションを利用して情報を付加するときに、リクエストパラメータには@Parameter
を利用すべきであることを紹介しました。
では、また次回。