REST-APIを多種類のプログラミング言語から呼び出す
ある単一の定義されたRest-APIを、多くの種類プログラミング言語から呼び出したい。もちろん、言語ごとにコードを手作業で作成するのは面倒なので、何とか自動生成できないものか。
現在のところ最大限考えられるのは以下だ。
- 通常のJavaアプリ
- Java-GWTクライアント
- C#
- Delphi
サーバ側としては、サーブレットを予定している。JAX-RSである。
大分類
大きなやり方としては二種類に分けられるように思う。
- そもそもJAX-RSではなく、別のAPI定義言語を使い、そこからJAX-RSも含めて自動生成する。
- JAX-RSを元定義とし、そこから多言語のクライアント用コードを生成する。
API定義言語を用いる方法
APIの定義言語としては、RAMLやらOASやらがあるようだ。ここから多種類のプログラミング言語のジェネレータがあるのかは未調査。
API定義言語を使い、そこからクライアントを自動生成するものとしては、例えばRAML Client Generatorというものがある。どの程度使えるものかは不明。
しかし、この方法には問題がある。今回、サーバ側としてはJAX-RSを使用することに決定しているので、もしこのようなAPI定義言語を使うことにすれば、それら2つのコードを別々にメンテしなければならなくなる。
例えば、RAMLを使用した場合で、かつ仮にRAMLからサーバ側のJAX-RSテンプレート生成機能があったとしても、APIの修正を行うには以下の手順を踏まないといけない。
- RAMLを修正する
- RAMLからJAX-RSのコードテンプレートを出力する
- 既にあるJAX-RSのコードと手作業でマージする
これはいかにも面倒だ。
JAX-RS定義から多言語クライアントコードを自動生成
上述とは別に、JAX-RSのコードをその「定義」としてしまい、そこから何とか多言語用のクライアントコードを生成できないものだろうか?
WADL
JAX-RSのコードからWADLというものを作成する機能がJerseyにはある。
これはxmlによってRESTを定義するもののようだ。WADLからJavaクライアントコードを生成するものとしてwadl2javaというものがあるという。
他の言語用は無いかもしれないが、XMLを読み込み処理するプログラムは書けるかもしれない。
※しかし、困ったことに、JAX-RSからWADLを生成するためには、ウェブサーバを動作させないといけない。先の投稿にあるように、
public static void main(String[] args) {
JdkHttpServerFactory.createHttpServer(
URI.create("http://localhost:8080/"),
new ResourceConfig().packages(true, "server"));
}
などと、最低限でもJersey内部のウェブサーバを起動し、ウェブアクセスしないとWADLが得られないようなのだ。なぜこんなことになってるのかわからないのだが、これでは使い物にならない。少なくともコンパイル済のJAX-RSコードからコマンドラインでWADLが得られねば話にならない。
JAX-RSからドキュメントを生成
ちなみにJAX-RSからドキュメントを生成するにはどうすればよいか?
JAX-RS Analyzer
というものがある。
これは単純にドキュメントを作るだけのようだ。特にSwaggerというものを生成する。
※現在はOpen API Specと呼ばれているようだ。
MicroProfile
JAX-RSの定義をOpen API Specによってドキュメント化する話。
説明されているアノテーションを使うには、現時点(2019/7)で以下。
compile group: 'org.eclipse.microprofile.openapi', name: 'microprofile-openapi-api', version: '1.1.2'
まとめ
今のところ以下のようなイメージだろうか。
- 多言語のクライアントコードの生成
JAX-RSからJerseyを使い、WADLを生成。WADLを読み込み、Javaオブジェクトに変換し、そこから対象の言語コードを生成する。 - ドキュメントの生成
MicroProfileアノテーションを使って、JAX-RSをアノテーションし、文書作成。