1.5.xで自動生成されたSwagger定義をカスタマイズする

  2015年7月23日

著者:オーレ・レンスマー

最近の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アノテーションに加えられた唯一の改善と追加ではありません。他にも以下のようなものがあります。

  • カスタムレスポンスヘッダーを追加するための@ResponseHeaderアノテーションを追加
  • @ApiParamにおける範囲値のサポートを改善
  • @ApiOperationごとに複数のタグを設定する機能を追加
  • コンテナベースの応答/パラメータのサポートを改善。

いつものように、何か不足しているものや問題が見つかった場合は、GoogleグループまたはGitHubまでご連絡ください。問題を解決し、Swaggerをさらに良くするために協力しましょう!