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をアノテーションし、文書作成。