なにか作る

なにかを作るブログです。

JAX-RS の REST API ドキュメントを Swagger を使って生成する

REST API を作っていると、やはりその API の概要を記したドキュメントを作る必要に迫られてくる。もちろん Markdown なんかで書いてもいいとは思うんだけど、そこそこ面倒な作業ではあるので、できれば自動化したい。Java EE には、もちろんそんな気の利いた仕様は定められていないので、何らかの便利なライブラリを探すことになる。

JAX-RSREST API ドキュメントを作成できるツール・ライブラリ

探してみたけれど案外少ない。見つけた限りではこんなのがあった。

名前 GitHub starred 特徴
MireDot - 無償版 basic と有償版 pro がある。どちらも使用にはライセンスキーが必要。
Maven プラグインと Gradle プラグインがある。
Enunciate 133 Maven プラグインあり。
Swagger Core 2559 アプリケーションに組み込む形式。プログラミング言語非依存。API の簡易実行機能付き。

どれも一長一短ありそうだが、一番普及している Swagger Core を使ってみようと思う。

Swagger について

Swagger は始めちょっと複雑に感じる。仕様と実装に別れている点は把握しておこう。とりあえず以下の要点だけ覚えておく。

名前 説明
Swagger Spec REST API に対する言語非依存のインターフェース仕様
Swagger Core JAX-RS, Servlet, Play Framework に対応した Swagger Spec の実装
Swagger UI SWagger 準拠 API から動的にドキュメントを生成するツール

詳しくは Developers.IO さんの記事に書かれているのでそちらを見るのが吉。

導入方法

基本的には GitHubWiki に記された導入方法に従うだけだが、Swagger のバージョンや JAX-RS の実装・バージョンによって微妙に方法が異なってくるのでその点には注意。

今回使用するソフトウェア類は以下の通り。

依存性の定義

JAX-RS 2.0 に対応しているのは swagger-jersey2-jaxrs。Jersey 2 向けではあるが、一部の機能を除いて RESTEasy でも使用できるそうだ。

build.gradle

dependencies {
  compile 'com.wordnik:swagger-jersey2-jaxrs:1.5.1-M2'
}
RESTEasy (WildFly) を使う場合の注意

条件不明だけど RESTEasy を使用しているときに、例外が発生して AP サーバーが起動できないことがあった。そのときには、swagger-jersey2-jaxrs の推移的依存性である jersey-media-multipart を除外してあげると動いた。

build.gradle

dependencies {
  compile('com.wordnik:swagger-jersey2-jaxrs:1.5.1-M2') {
    exclude module: 'jersey-media-multipart'
  }
}

Swagger の有効化と設定

  • JAX-RS を有効化するためには Application クラスのサブクラスを用いる。
  • getClasses メソッドをオーバーライドする形となるので、独自作成したリソースクラスは、すべて手動で登録する。
@ApplicationPath("api")
public class ApplicationConfig extends Application {

  private static final String RESOURCE_PACKAGE = "com.example.web.resource";

  public ApplicationConfig() {
    // Swagger の設定
    BeanConfig beanConfig = new BeanConfig(); 
    beanConfig.setVersion("0.0.1");
    beanConfig.setSchemes(new String[] {"http"});
    beanConfig.setHost("localhost:8080");
    beanConfig.setBasePath("/v1");
    beanConfig.setResourcePackage(RESOURCE_PACKAGE);
    beanConfig.setScan(true);
  }

  @Override
  public Set<Class<?>> getClasses() {
    Set<Class<?>> resources = new HashSet<>();

    // JAX-RS のリソースクラスの登録
    new Reflections(RESOURCE_PACKAGE).getTypesAnnotatedWith(Path.class).forEach(resources::add);

    // Swagger の有効化
    resources.add(com.wordnik.swagger.jaxrs.listing.ApiListingResource.class);
    resources.add(com.wordnik.swagger.jaxrs.listing.SwaggerSerializers.class);

    return resources;
  }

}

ドキュメント用の情報の埋め込み

Swagger を有効化した後は、いろいろ付与できる情報はあるみたいなのだが、ここでは 2 つだけ紹介。

アノテーション 説明
Api Swagger のリソースとしてクラスをマークする。
ApiOperation リソースに対する操作に関する情報を記述する。
@Path(CountryResource.PATH)
@RequestScoped
@Api(value = CountryResource.PATH, description = "国に関する操作")
public class CountryResource {

  static final String PATH = "/country";

  @Inject
  private CountryRepository repository;

  @GET
  @Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8")
  @Transactional
  @ApiOperation(value = "すべての国情報を取得", response = Country.class, responseContainer = "List")
  public List<Country> getAll() {
    return repository.getAll();
  }

}

Swagger が動作していることの確認

アプリケーションを AP サーバー上にデプロイした後、Swagger の API にアクセスする。JAX-RS のベースとなる URL の下の /swagger.json にアクセスして、いい感じの JSON が取得できれば成功。

例)http://localhost:8080/app/api/swagger.json

Swagger UI の配置と Swagger API の参照

Swagger UI のリポジトリ から Swagger Spec 2.0 に対応した 2.1.x をダウンロードして、dist フォルダーを Web サーバー上に配置すれば完了。index.html にアクセスして画面上部のテキストボックスか url クエリ文字列に上記の URL を入力すればドキュメントが表示される。

URL 例)http://localhost:8000/index.html?url=http://localhost:8080/sample-web-project/api/swagger.json

f:id:ptiringo:20150506151128p:plain

※CORSの対応が必要な場合は、別途対応する。

参考サイト