著者:オーレ・レンスマー
最近のJava用Swaggerコアツールは、SwaggerランタイムがAPIのSwagger定義を生成するために使用するコアアノテーションに多くの機能を追加しました。これらの機能を簡単に見て、ボトムアップアプローチでSwagger定義を作成する際に、より完全なAPIメタデータを提供する方法を確認しましょう。
@SwaggerDefinition
@SwaggerDefinitionアノテーションは、コアアノテーションへの最大の追加です。生成されたSwaggerに定義レベルのメタデータを追加する手段を提供し、すべてSwagger 2.0仕様のSwaggerオブジェクトのプロパティに直接関連しています。
- info - API全体のメタデータを提供します(タイトル、説明、ライセンスなど)。
- consumes - この定義で説明されているAPIによって消費されるMIMEタイプのグローバルリスト
- produces - この定義で説明されているAPIによって生成されるMIMEタイプのグローバルリスト
- schemes - このAPIがサポートする転送プロトコル
- basePath - Swaggerランタイムによって推測されたbasePathをオーバーライドします。
- host - Swaggerランタイムによって推測されたホストをオーバーライドします。
- tags - 追加のメタデータとともに仕様で使用されるタグのリスト。
- externalDocs - 追加の外部ドキュメント参照
このアノテーションは、Swaggerランタイムによってスキャンされる任意のクラスに配置できます。たとえば、プロジェクト内にこのアノテーションのみを持つ空のインターフェースを作成し、一般的なAPIメタデータとAPIリソースに固有のメタデータを分離することができます。例として、これを標準のJAX-RSリソースの隣に配置すると
@SwaggerDefinition(
info = @Info(
description = "私のAPI",
version = "V1.2.3",
title = "私について知るために必要な唯一のAPI",
termsOfService = "共有とケア",
contact = @Contact(name = "スポンジ・ボブ", email = "[email protected]", url = "https://swagger.dokyumento.jp"),
license = @License(name = "Apache 2.0", url = "https://apache.dokyumento.jp"),
consumes = {"application/json" },
produces = {"application/json" },
schemes = {SwaggerDefinition.Scheme.HTTP, SwaggerDefinition.Scheme.HTTPS},
externalDocs = @ExternalDocs(value = "私について", url = "http://about.me/me")
)
public interface MyApiDefinition {}
結果として、生成されたSwagger定義にこれが追加されます。
{
"swagger": "2.0",
"info": {
"description": "私のAPI",
"version": "V1.2.3",
"title": "私について知るために必要な唯一のAPI",
"termsOfService": "共有とケア",
"contact": {
"name": "スポンジ・ボブ",
"url": "https://swagger.dokyumento.jp",
"email": "[email protected]"
},
"license": {
"name": "Apache 2.0",
"url": "https://apache.dokyumento.jp"
},
"schemes": [
"http",
"https"
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {
...
SwaggerDefinitionアノテーションの詳細については、wikiおよび対応するjavadocを参照してください。
@Extension
拡張アノテーションを使用すると、Swagger定義に拡張プロパティを追加できます。現在、@ApiOperation、@Info、および@Tagアノテーション内でサポートされています。使用方法は2通りあります。
...
extensions = {
@Extension(properties = {
@ExtensionProperty(name = "test1", value = "value1"),
@ExtensionProperty(name = "test2", value = "value2")
})
}
...
結果として以下のJSONが得られます。
...
"x-test1" : "value1",
"x-test2" : "value2"
...
プロパティ名に明示的に"x-"が付けられていない場合、アノテーションによって自動的に"x-"が接頭辞として追加されます。
または、拡張機能を次のように命名することもできます。
...
extensions = {
@Extension( name = "my-extension", properties = {
@ExtensionProperty(name = "test1", value = "value1"),
@ExtensionProperty(name = "test2", value = "value2")
})
}
...
結果として以下のJSONが得られます。
...
"x-my-extension" : {
"test1" : "value1",
"test2" : "value2"
}
...
これにより、含まれる拡張プロパティがJSONオブジェクトにラップされます。
ReaderListener
これらのアノテーション拡張機能でもSwagger定義を思い通りに作成できない場合は、Swaggerランタイムの前後で呼び出されるReaderListenerを作成することを選択できます。この拡張機能は、すべてのSwaggerおよびJAX-RSアノテーションを読み取り、対応するSwagger定義を構築します。いずれかのハンドラを実装することで、生成された定義を完全に制御でき、好きなように変更できます。
- セキュリティ定義またはカスタムモデルオブジェクトを追加する
- コンテキスト属性に基づいて不要な情報をフィルタリングする
- 他の場所で定義されたAPI定義を読み取り、追加する
- など。
必要なのは、ReaderListenerインターフェースを実装するクラスを提供し、そのクラスがSwaggerランタイムが使用するクラスパススキャナーによって見つけられるようにすることだけです。上記のように@SwaggerDefinitionアノテーション付きインターフェースを作成した場合、それをクラスに変更してこのインターフェースを実装することができます。
@SwaggerDefinition(...)
public class MyApiDefinition implements ReaderListener {
public static final String TOKEN_AUTH_SCHEME = "tokenAuthScheme";
public static final String ACCOUNT_READ_SCOPE = "account_read";
public static final String ACCOUNT_WRITE_SCOPE = "account_write";
@Override
public void beforeScan(Reader reader, Swagger swagger) {
}
@Override
public void afterScan(Reader reader, Swagger swagger) {
OAuth2Definition tokenScheme = new OAuth2Definition();
tokenScheme.setFlow("password");
tokenScheme.setTokenUrl("https://" + swagger.getHost() + "/tokens");
Map<String, String> scopes = new HashMap<>();
scopes.put(ACCOUNT_READ_SCOPE, "私のデータを読み込む");
scopes.put(ACCOUNT_WRITE_SCOPE, "私のデータを更新する");
tokenScheme.setScopes(scopes);
swagger.addSecurityDefinition(TOKEN_AUTH_SCHEME, tokenScheme);
}
}
この例では、OAuth2 Password Credentials Grantセキュリティ定義を追加しています。これには、@ApiOperationアノテーションで次のように参照できます。
@ApiOperation(value = "Updates user data",
authorizations = @Authorization(value = MyApiDefinition.TOKEN_AUTH_SCHEME, scopes =
@AuthorizationScope(scope = MyApiDefinition.ACCOUNT_WRITE_SCOPE, description = "ユーザーデータへの書き込みアクセス")))
public Response updateUser( UserData data ) throws NotFoundException {
...
}
ReaderLicenserはSwagger Coreプロジェクト内のJAX-RS実装モジュールに固有であるため、io.swagger.swagger-jaxrsモジュールで利用可能であり、上記で説明した他のものとは異なり、io.swagger.swagger-annotationsでは利用できません。
アノテーションのさらなる改善
上記はSwaggerアノテーションに加えられた唯一の改善と追加ではありません。他にも以下のようなものがあります。
いつものように、何か不足しているものや問題が見つかった場合は、GoogleグループまたはGitHubまでご連絡ください。問題を解決し、Swaggerをさらに良くするために協力しましょう!