Swagger、GraphQL、gRPC+Protocol Buffersの概観

# この記事について
この記事は、DroidKaigi2018の以下の発表に刺激を受けて書いた記事です。

- [まだAPI定義管理で消耗してるの？〜Swaggerを用いた大規模アプリ時代のAPI定義管理とコードジェネレート〜](https://speakerdeck.com/magiepooh/madaapiding-yi-guan-li-dexiao-hao-siterufalse-swaggerwoyong-itada-gui-mo-apurishi-dai-falseapiding-yi-guan-li-tokodozienereto)
- [すばらしきGraphQLのSEKAIへようこそ](https://speakerdeck.com/gfx/subarasikigraphqlfalsesekaiheyoukoso)
- [gRPCとProtocol Buffersで一味違うAndroid通信](https://speakerdeck.com/kmats/protobuf)

上記の発表では、Swagger、GraphQL、gRPCとProtocol Buffersという言葉が出てきました。これらはサーバー/クライアント間のAPI通信を実現するために役立つものです。しかし、Swaggerはツール、GraphQLはクエリ言語、gRPCとProtocol Buffersは設計指針（を実装したライブラリ）とデータフォーマットというように同格に扱えるものではないので、ちょっと混乱してしまいます。

そこで、この記事ではサーバー/クライアント間のAPI通信に関する上記の3つの手法を紹介し、各手法がAPI通信に必要な要素をどのように満たすのかを比較します。私はREST API（Swaggerなし）しか触ったことがなく、DroidKaigiでの発表で聞いたこと+自分で調べた範囲での理解になりますので、間違っている際はマサカリお願いします。

あと、発表を聞いた感想も載せています。

# 各技術の紹介
Swagger、GraphQL、gRPC+Protocol Buffersについて簡単に紹介します。詳しいことについては、DroidKaigiの各発表資料を見ると良いです。発表の動画も近日公開予定だと思われます。

## Swagger
https://swagger.io/

SwaggerはAPIの定義からドキュメントを生成するツールです。YAMLやJSONでAPI定義を書きます。[オンラインエディター](https://editor.swagger.io)で、API定義からどのようにドキュメントが生成されるのかを見ることができます。

また、[Swagger Codegen](https://github.com/swagger-api/swagger-codegen)を使うとAPI定義から実装クラスを生成してくれます。さらに、モックサーバーを立ち上げることもできます。

## GraphQL
http://graphql.org/

GraphQLはSQLのようなクエリ言語の一種です。一度のリクエストで複雑な情報を取得することができます。

http://graphql.org/learn/ でスキーマ定義とGraphQLのリクエスト、JSONのレスポンスの例を見ることができます。

## gRPC+Protocol Buffers
gRPC: https://grpc.io/
Protocol Buffers: https://developers.google.com/protocol-buffers/

gRPCはRPCと呼ばれるAPIの設計指針をGoogleが実装したものです。Protocol BuffersはJSONやXMLのようなデータフォーマットです。gRPCが対応しているデータフォーマットがProtocol Buffersです。


# 各技術を使ったAPI通信の比較
サーバー/クライアント間のAPI通信を実現するために必要な要素はさまざまです。それらを列挙して、各項目ごとにSwagger、GraphQL、gRPC+Protocol Buffersを使った手法で、どのようになっているかを比較します。

## 比較する要素
API通信を実現するための要素として、今回は以下を比較します：

- 通信プロトコル：今回紹介するものは全てHTTPで実現可能
- APIの設計指針：パス、HTTPメソッド、HTTPレスポンスコードなどをどう扱うか
- リクエストデータ：JSON, XML, Protocol Buffers, GraphQL
- レスポンスデータ：JSON, XML, Protocol Buffers
- スキーマからのコード生成：SDD(Schema-Driven Development)を実現するために、スキーマ（API定義）からコードを生成する方法


## 比較表  
|  | Swagger | GraphQL | gRPC+ProtoBuf |
|:-----------|:------------|:-------------|:--------------|
| 通信プロトコル ※1 | HTTPなど | HTTPなど | HTTP |
| 設計指針 | REST | なし ※2 | RPC |
| リクエストデータ | JSON, XMLなど | GraphQL | Protocol Buffers |
| レスポンスデータ | JSON, XMLなど | JSON, XMLなど | Protocol Buffers |
| スキーマからのコード生成 | Swagger Codegen | Apollo | protocol buffer compilers |
| スキーマからのドキュメント生成 | Swagger | なし | なし |

※1 gRPCはHTTPで実現されています。Swagger(REST)やGraphQLはHTTPが主流なだけで、別の通信プロトコルでも実現は可能です。
※2 GraphQL自体はクエリ言語なので設計指針はありませんが、[GitHubの設計](http://graphql.org/learn/serving-over-http/)が参考になります。

## どれが良いか？
今回の比較表から優劣を決めることはできないと考えています。各技術によって得意とするところが変わってくるので、一概にこれが良いとは言えません。

たとえば、RESTはリソースの取得を定義するのに向いているが更新系のアクションを定義するのにはRPCが向いている、Protocol Buffersは高速だがバイナリなのでJSONやXMLのように読むことは難しい、といったようにメリットやデメリットがそれぞれあります。

月並みですが、自分たちのプロダクトやチーム状況に合わせて選択するのが良さそうです。

# 発表を聞いた感想
最後に、DroidKaigiでAPI通信に関する3つの発表を聞いた感想を載せておきます。

- どの発表もわかりやすく、ためになった。
- SDD(Schema-Driven Development)が熱い。API定義からのコード生成などによってすぐに開発に移れるという認識をした。API定義が決まってからコードに落とし込むところが半自動化されるのは嬉しい。
- RESTでHTTPが見えちゃってる感あるのは、確かにそうだな。GraphQLとgRPCは上手くHTTPをラップしている感じがする。
- 現状RESTでAPIを作っているので、導入はSwaggerが一番楽そう（自分は触ってないがチームで少しだけ使われている）。