読者です 読者をやめる 読者になる 読者になる

OpenAPI Specification と Swagger Codegen に至るまで辿った道

ポエムです。コードが1行も出てこないので じっちゃん に怒られそうです。

Remote Procedure Call(RPC)に長年興味を持ち、実案件で使ってきました。
RPC は、ネットワーク上にあるロジックを関数呼び出しで実行することができ、通信のためのコードを隠蔽する技術と考えています。
RPCに関し、OpenAPI Specification(Swagger Codegen)に辿り着くまでの道を振り返ってみました。

f:id:t1000leaf:20170318083059p:plain

CORBA

www.corba.org

CORBA の歴史は長いみたいですが、私が実案件で使ったのは今世紀に入ってからだったと思います。
「分散オブジェクト」という言葉の響きで中二心を揺さぶられました。
VisiBroker, Orbix といった実装を使っていましたが、もうすっかり忘れてしまいました。
IDL(インターフェース記述言語)、スタブ、スケルトンという言葉をこの時、知りました。
IDL を書いて、クライアントのスタブ、サーバのスケルトンのコードを自動生成するアプローチですね。
そして今、CORBA が息をしているかも知りません。

RMI

f:id:t1000leaf:20170318020844p:plain

RMI も実案件で使いました。
Java 限定なので IDL も不要でシンプルだと思いました。
Java5 の頃に利用し今でも気に入っています。
デメリットとしては、サーバ側に変更が入ると、クライアント側も同じタイミングでデプロイしないといけないということでしょうか?
頻繁に変更することがなかったためか、それで困ったことはなかったです。

SOAP

  • Simple Object Access Protocol
  • XMLベースのRPCプロトコル
  • サポートされる異言語間の通信が可能
  • HTTPベース

CORBA の HTTP 版みたいな感じで、Firewall を超えやすいといったところでしょうか。
実案件で使ったのはクライアント側だけです。
SOAP は今でもちょっと使われている感があります。

Thrift

f:id:t1000leaf:20170318080551p:plain

Apache Thrift - Home

  • 「スケーラブルな言語間サービス開発」のためにFacebookにて開発されたRPCフレームワーク
  • サポートされる異言語間の通信が可能
  • Facebook が作ったオレオレ CORBA

CORBA を今風に改良した感じでしょうか。
実案件でクライアント側を使ってきました。
Javaクライアントを開発してたはずなのに、デカめの Scala のランタイム jar が Maven レポジトリから降臨してきた時に、ナヌーって声に出してしまいました(Thiriftじゃなくfinagleの依存だったかな)。

gRPC

f:id:t1000leaf:20170318015145p:plain

www.grpc.io

  • Google にて開発されたHTTP/2ベースのRPCフレームワーク
  • サポートされる異言語間の通信が可能
  • Protocol Buffers(default)

Google が作った オレオレ CORBA といったところでしょうか。
最近 1.0 になったばかり。
Thrift の後発で競合しそうです。
HTTP2 ベースということで、AndroidiOS からの利用も期待できそうです。
実案件では使っていません。
ちょっと試したところ、Java サーバアプリのビルドで、C++コンパイラが必要になりちょっと萎えました。

でだ

RPC というアプローチはインターフェースをちゃんと定義し良いと思うんですが、なかなか周りに受け入れらる感触がないです。
なんか難しそうという印象を与えてしまう。
クライアント(利用者)側から依存ライブラリ増やしたくないんだよと言われる。

f:id:t1000leaf:20170319093715p:plain

REST

みんな大好き REST !
バズワード的に広まったマイクロサービスもデフォルトが REST とされています。

  • Representational State Transfer
  • HTTPベース
  • レスポンスは XMLJSON

私は、REST より SOAP だろうと思ってた人です。
REST は インターフェース定義が不明確。
クライアントが Web ブラウザなら良いと思うけど。。
みんな、おのおのに同じようなクライアントのコードを書いて楽しい?疲れない?
嘘だらけのAPI仕様ドキュメント

じゃあ逆に、REST を RPC の方に寄せられないだろうかと思うようになりました。
明確にインターフェースを定義できれば RPC 的な事が実現できるはず。。

WADL

そもそも REST における WSDL みたいなインターフェース定義みたいなのないの?と思っていたところ、WADLを発見しました。

  • Web Application Description Language
  • World Wide Web Consortium (W3C) により提案
  • XML で REST の Interface を定義

しかーし、この存在知ってる人あまりいないですよね !

そして、2015年、、

Open API Initiative

f:id:t1000leaf:20170318020147p:plain

Open API Initiative

  • REST API のインターフェースを記述するための Standard format を推進する団体
  • 2015-11-05 Google, Microsoft, IBM etc により結成

(゚∀゚)キタコレ!!
でも やってる事 WADL とかぶってないか。

OpenAPI Specification(Swagger)

github.com

で、 Open API Initiative が推進する OpenAPI Specification です。
もともと Swagger というフレームワークがあり、それをベースにしています。
XML ではなく今風に YAML, JSON でインターフェースを定義します。
Swagger Editor でインターフェースを定義することができます。

editor.swagger.io

Swagger のメリットは、二つあると思います。
一つは、インターフェースを定義することにより、ドキュメントの自動生成や Swagger UI により インターラクティヴな実際に REST クライアントとして動くドキュメントを生成できます。

以下は、Swagger UI の例です。
http://petstore.swagger.io

f:id:t1000leaf:20170318021211p:plain

もう一つのメリットは、RPC を実現する Swagger Codegen です。

github.com

インターフェース定義からサーバ・クライアントのコードを自動生成します。様々な言語・フレームワークのコードを生成できます。
また生成されるコードが気に入らない場合は、自分でカスタマイズできます。
下記は、対応する言語・フレームワークです。

Client

Server

デメリットとしてコード生成系のプロダクトはどうしてもバグが入りやすくなる感じで、プロダクトに対して利用者がコントリビュートしていかなければいけないところだとは思います。

SpringFox

SpringFox by springfox

実際、私は Swagger をどう利用しているかといいますと、インターフェス定義を直に書いていません。
Java の Spring MVC と SpringFox というライブラリを利用することにより、サーバアプリからインターフェース定義を自動生成しています。
そのインターフェース定義からクライアントのコードを自動生成して提供しています。
SpringFox の一つの不安は、Spring の中の人は、たぶん Swagger に関心がないのでは?というところ。
Spring REST Docs というドキュメントだけ生成する仕組みを別に持っています。
Swagger のように実装コードにドキュメンテーション用のコードが入ることを嫌い、それはテストコード側にあった方が良いという考えだと思います。
個人的には、Spring に SpringFox 自体を取り込んでも良いのでは?と思うところですが。
Sinatra にインスパイアされた系のフレームワークより、 Spring MVC みたいなリフレクションベースのフレームワークの方が、Swagger と相性が良いんですよね。
Spring MVC はメソッドのシグネチャ見れば、RESTの仕様も分かっちゃうんで。
SpringFox のデメリットは、アプリサイズが大きくなることです。SpringFox が guava に依存していて、そのサイズが2.2Mあるのです。guava依存外せないものかなー。
ここのスライドでは、31MB と書いてあるんですが、ランタイムでそんなに増えることは決してありません。これを見て SpringFox 使うの諦めた人がいるかも。。

Swagger で Web バックエンドと Web フロントエンドをタイプセーフにつなぐ

以前に書いた記事ですが、TypeScript のコードを生成することにより、Web バックエンドと Web フロントエンドがタイプセーフに繋がります。

tc.hatenablog.com github.com

まとめ

OpenAPI Specification(Swagger) は、クライアント側に二つの選択肢を与えます。
RPC なんて嫌だという人は、 Swagger UI を見てクライアントのコードを実装できます。
タイプセーフにしたいから RPC が良いという人は、 Swagger Codegen でクライアントのコードを得る事ができます。
RPC的なアプローチをクライアント側に対して押しつける必要もありません。
クライアント側は自由です。
妥協点というか、落とし所を見つけた感じであります。はい。

f:id:t1000leaf:20170319224409p:plain

(記事の中でマイクロサービスやらSOAとかの言葉を使った方が釣りやすいと思ったけど止めた)

以上

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

マイクロサービスアーキテクチャ [ SamNewman ]
価格:3672円(税込、送料無料) (2017/3/19時点)