概要
API通信処理、どんな方法で実装していますか?
クライアントアプリを開発してると何かと書く機会が多い部分ですが、アプリごとに頑張って書いていくの面倒ですよね。
同じ言語ならライブラリとして切り出せば良いですが、プラットフォームが違う場合は大抵言語も違うので、その場合は再開発する必要が出てきて辛いですよね。
そういう時はSwaggerを使うとその問題解決、あるいは軽減できるかもしれません。
今回はSwaggerを使った通信処理を自動生成する方法を紹介したいと思います。
こんな人にオススメ
- APIドキュメントの追従や管理がつらい
- プラットフォームごとに実装書くのつらい
- JSONをいい感じにパースするライブラリがない
- (もしくはあるけど実装がめんどい)
- APIガッツリ使うプロダクトなのに、開発開始直後でサーバー側にAPIが用意されてない
- 結合まで待ってたら作業進まない
javaはGsonとかjsonicとかアノテーションベースでパースできるからあんまし気にしてなかったけど、iOSで簡単なアプリ作ってた時は個人的には面倒に感じていました。
Swaggerとは
特徴
- yamlもしくはjsonからAPIの通信処理が自動生成できる
- 言語も一つノファイルから複数に書き出せる
- 書き出したファイルからAPIドキュメントが自動生成できる
- ファイルを修正していけば、通信処理のコードも新しくなってくしドキュメントも追従されていく
- メンテの忘れで乖離が発生しにくくなる
- 書き出したファイルからモックレスポンスを返すサーバーを立てれる
インストール
自動生成するための環境自体はすぐに用意できる
mac
$ brew install swagger-codegen
linux
$ wget http://central.maven.org/maven2/io/swagger/swagger-codegen-cli/2.2.2/swagger-codegen-cli-2.2.2.jar -O swagger-codegen-cli.jar
試しにコードを自動生成してみる
コマンドの-l
オプションに生成したい言語のコードが生成される
mac
swagger-codegen generate -l java -i hoge.yml -o build/output/
linux
java -jar bin/swagger-codegen-cli.jar generate -l java -i hoge.yml -o build/output/
yamlからAPIのドキュメントとスタブサーバーを自動生成する
nodejsで立てる場合はこんな感じ
$ swagger-codegen generate -l nodejs-server -i hoge.yml -o build/output/
$ cd build/output/ && node index.js
立ち上げるとドキュメントとモックが返るURLが用意される。モックは定義したAPIのリクエストからレスポンスを適当な文字や数字で返してくれる。
- ドキュメントを見る場合
http://localhost:3000/doc
- モックを見る場合
http://localhost:3000/{定義したAPIエンドポイント}
所感
- 面倒なAPIクライアント処理を自動生成できるのは便利
- APIドキュメントに流用できるので、wikiで頑張って管理しなくて良い
- 後述するswagger-playあたりを活用すれば、コードとドキュメントの乖離を減らすこともできる
- stubサーバーが返すレスポンスは貧弱
- これに関しては良いライブラリを見つけたので別記事で紹介する
- 自動生成されるコードの依存が古い
- バージョンアップの期間に幅があるので、そこらへんは少し心配かもしれない。
Android開発から見たSwagger
-
RxJava が使える
- ただしRxJava2は非対応
- 最近PRがマージされたようなので直近で対応されるかも
-
Retrofit が使える
- こちらはRetrofit2も対応
Android開発だけで見ると、Retrofitのおかげで大分開発しやすいので恩恵は薄いですが、他の言語にも使えるフォーマットから自動生成できるのは便利ですね。
あとドキュメントなどにも応用できるなど考えると、導入するメリットはそれなりにありそう に感じました。
Swaggerは何にでも使える便利な仕組みなのか
そんなことはないと思います。
中には表現できないAPIも存在します。
複雑な配列を返すようなものは現状厳しそうです。
(anyOf的な表現が非対応)
ただ継承関係みたいな表現は可能なので、うまくやれば大体の構造はいけると思います。
ここらへん参照
http://swagger.io/specification/
おまけ
サーバー側の実装から生成できないの?
せっかくサーバー側でリソースやエンドポイントも定義して実際の処理はそっちで書かれるのにyamlにも書くの?と思うかもしれませんが、yaml以外の方法でもSwaggerのファイルを生成することができます。
swagger-play
アノテーションベースでSwaggerを定義できるっぽい。
自前でAPI用意する場合はこういうのからSwaggerを生成する方が現実的な気がしますね。