今回はSwagger Coreを紹介します。
設計(Swagger Spec)からコードを生成する、いわば順方向にあたるのが、前回紹介したSwagger Codegenです。一方で、コードから設計(Swagger Spec)を生成する、いわば逆方向にあたるのが今回のSwagger Coreです。
Swaggerに限らず、自動生成の種別として順方向・逆方向の2つのアプローチがあり、どちらを中核に置くか(マスタとするか)によって、それぞれ使いどころが異なります。
Swagger CoreはAPIコードにアノテーションを付与することで、Swagger Spec仕様を記述したJSONファイルを自動生成できます。あくまでコードを中心に置き、コードにアノテーションをつけるという意味では、Javadocに近い発想です。
インストールと設定
前提環境を構築するため、Spring Bootをインストールします。詳細は拙著「APIエコノミーの作り方」の第六回「APIの組み合わせの勘所」をご参照ください。
ブラウザからSpring Initializerにアクセスし、以下の通り入力します。Generate Projectをクリックすると、資材一式(demo.zip)がダウンロードされます。
DemoApplicationを以下の通り設定します。APIは以下の通り、ルートからの相対パス「/」にアクセスすると、「Hello World!」と返す簡易なものです。
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication
public class DemoApplication {
@RequestMapping("/")
String hello() {
return "Hello World!";
}
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleBoot.class, args);
}
}
pom.xmlにインストール対象を記載します。Swagger Coreの他にSpringFoxを使います。
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.0.3</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.0.3</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-core</artifactId>
<version>1.5.10</version>
</dependency>
以下の通りConfigurationクラスを用意します。
package com.example;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import springfox.documentation.builders.RequestHandlerSelectors;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket swaggerSpringMvcPlugin() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example"))
.build();
}
}
RequestHandlerSelectorsクラスのbasePackageメソッドを見ると、Swagger Specが生成される対象がcom.exampleパッケージであることがわかります。また、DemoAppicationクラスをいじることなくSwaggerの設定を追加することができました。
機能紹介と基本的な使い方
ターミナルからAPIをビルドおよび起動します。これによりSwagger Spec仕様のJSONファイルと、Swagger UIを使ったAPI仕様ドキュメントが生成されます。
$ ./mvnw spring-boot:run
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building demo 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
2017-02-05 23:52:31.136 INFO 31834 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2017-02-05 23:52:31.144 INFO 31834 --- [ main] com.example.DemoApplication : Started DemoApplication in 4.022 seconds (JVM running for 7.44)
ブラウザやcurlコマンドなどを用いて「localhost:8080/v2/api-docs/」にアクセスします。以下の通りSwagger Spec仕様のJSONファイルが返却されます。
{"swagger":"2.0","info":{"description":"Api Documentation","version":"1.0","title":"Api Documentation","termsOfService":"urn:tos","contact":{},"license":{"name":"Apache 2.0","url":"http://www.apache.org/licenses/LICENSE-2.0"}},"host":"localhost:8080","basePath":"/","tags":[{"name":"demo-application","description":"Demo Application"}],"paths":{"/":{"get":{"tags":["demo-application"],"summary":"hello","operationId":"helloUsingGET","consumes":["application/json"],"produces":["*/*"],"responses":{"200":{"description":"OK","schema":{"type":"string"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}}}}
ブラウザから「http://localhost:8080/swagger-ui.html/」にアクセスします。以下の通り、Swagger UIを使ったAPI仕様ドキュメントが返却されます。なお、Swagger UIの詳細については、本連載第二回「Swagger UIの準備」をご参照ください。
Swagger Coreのアノテーション仕様
上述ではSpringFoxを使ってSwagger Coreを動かしてみました。次に、Swagger Coreで標準的に対応しているJAX-RSアプリケーションに適用してみましょう。
Swagger Coreの適用対象とするクラスに対しては@Apiアノテーションをつけ、リクエストやレスポンスのパラメータについては、@ApiParamや@ApiResponseといったアノテーションで表現します。
@Path("/pet")
@Api(tags = {"pet"})
@Produces({"application/json", "application/xml"})
public class PetResource {
@GET
@Path("/{petId}")
@ApiOperation(value = "IDによるPetの検索", response = Pet.class)
@ApiResponses(value = {
@ApiResponse(code = 400, message = "無効なIDの指定"),
@ApiResponse(code = 404, message = "Petは見つかりません") }
)
public Response getPetById(
@ApiParam(value = "Pet ID", required = true)
@PathParam("petId")
Long petId) throws NotFoundException {
// 処理内容は省略。IDによるPetの検索処理
}
代表的なアノテーションは以下の通りです。
アノテーション一覧
アノテーション名 | 説明 |
---|---|
@Api | Swagger Coreによる生成対象のクラスとして扱う |
@ApiImplicitParam | 単一パラメータを受け付けるAPI |
@ApiImplicitParams | ApiImplicitParamオブジェクトのリストを受け付けるAPI |
@ApiModel | Swaggerモデルの情報を付与する |
@ApiModelProperty | Swaggerモデルのプロパティ情報を付与する |
@ApiOperation | オペレーション。多くの場合は特定パスに対するHTTPメソッドのことを指す |
@ApiParam | オペレーションパラメータに付与するメタデータ |
@ApiResponse | オペレーションのレスポンス |
@ApiResponses | ApiResponseオブジェクトのリスト |
@Authorization | リソースやオペレーションで利用される認可スキーム |
@AuthorizationScope | OAuth2の認可スコープ |
@ResponseHeader | レスポンスヘッダ |
実際にコーディングして動かしてみたい方はSwagger本家のGithubにてJersey2ベースのJAX-RSサンプルアプリが公開されていますのでご参照ください。
* * *
今回は、Swagger CoreおよびSpringFoxを用いてSpring BootベースのAPIからSwagger Spec仕様のJSONファイルを生成しました。また、同時にSwagger UIドキュメントも作成しました。
SwaggerはSwagger Specを中心に置き、ドキュメントとコードをシームレスにつなぐことができます。ドキュメントを先に書いてコードを自動生成するトップダウンのパターンの場合にはSwagger Codegenが利用でき、その逆の場合は今回のようにSwagger Coreが利用できます。
近年、Swaggerはエンタープライズアプリケーションの分野にとどまらず、さらにその活用の幅を広げてきています。例えば、ブラウザベースの統合開発環境であるEclipse Cheなど、GUIのツールでありながら、REST APIをベースとしたCUIのインタフェースを解放しているものが増えてきており、APIドキュメンテーションのためにSwaggerが採用されることが多くなってきています。Swaggerの使い方を学んでおくことは、開発者にとって必須となってくるでしょう。
次回は、API Management製品であるGoogleのApigeeとの連携など、APIを開発する上で、Swaggerをさらに幅広く活用する方法を紹介します。
著者紹介
正野 勇嗣 (SHONO Yuji ) - NTTデータ シニアスペシャリスト
2011年頃まで開発自動化技術のR&Dに従事。その後、開発プロジェクト支援やトラブルシューティング等に主戦場を移す。「ソースコード自動生成」に加えて、JenkinsやMaven等の「ビルド自動化」、JsTestDriverやSelenium等の「テスト自動化」を扱うようになり、多様化する開発自動化技術動向に興味。
最近は第四の自動化であるInfrastructure as Code等の「基盤自動化」の魅力に惹かれている。開発自動化技術に関する雑誌・記事執筆も行う。2児のパパ。