JAX-RSのClientAPIを眺めてみて
導入
もう随分前の話になるのだけれど、JAX-RS2.0にはClient APIが仕様に入っております。
それはそれとして、各実装は個別にClient APIを提供したりしておました。 個別に実装していたClientAPIには当然違いがあるわけです。で、どんな差があるんだろーと見てみることにした。
- JSR
- 実装
- Jearsey Client API 2.17
- RESTEasy Client API 3.0.9.Final
- Apache CXF 3.0.x?
JSRさん
斜め読みすると「Client
を取得してWebTarget
を生成し、WebTarget
からrequest
を作って送信する。」ものらしい。なるほど。
あとはWebTarget
使ったらいろんなアドレスへアクセスできるよーとか、レスポンスはResponse
だけじゃなくいろんなタイプが使えるよ!とか、buildGet
やbuildPost
でInvocation
を使ったら非同期的なことできんじゃね?とか、Configurable
インタフェース使って設定できるよーとか、インターセプター使えるよーとか、そんな感じ。
印象として、WebTarget
を使用したURIの指定方法がいろいろ用意されているのはREST APIゆえなのかなと思う一方で、FluentインタフェースだけだとJAX-RSとして入っている理由はあんまりなく、他に絡むのはProvider
とFilter
くらいなように見えます。クライアントとしては十分なのかもだけど。
各実装
目に付いた実装のドキュメントを読んだり試してみたりしつつ。
Jerseyさん
参照実装であるJerseyさん。これを元に仕様化したということで、特にいびつさはないです。表面に出てくるのはJAX-RSのインタフェースだけなので、この書き方は全てのJAX-RS2.0実装で使えます。
Station station = ClientBuilder.newClient() .target(BASE_URL) .queryParam("number", number) .request() .get(Station.class);
他には、rx(Reactive Extension)の実装があります。
詳しくは @backpaper0 さんちに書いて……
Jersey ClientのRxサポートを軽〜く試す — 裏紙
……詳しくなかったわ。
RESTEasyさん
RESTEasyさんは元々ProxyFrameworkと言う別のクライアント実装を提供していた。それと仕様化されたクライアントの共存みたいな感じになっている。 このProxyFrameworkの強みはServerとClientでインタフェースを共有できる点かな。あとは一つのサービスの多くの種類のAPIを叩く場合にはインタフェースに分かれてるとやりやすいかもしれない。コードでURIを組み立てるか、インタフェースにアノテートするかの選択ができる。Jerseyのところで挙げた書き方もできるし、次のようにも書ける。
Station station = new ResteasyClientBuilder().build() .target(BASE_URL) .proxy(StationServiceProxy.class) .station(number);
ResteasyClientBuilder
は先に挙げたClientBuilder
のサブクラスだけど、ビルド手順が標準化されたのと違う感じになるので、どうしても歪さは出てくる。ClientBuilder#newClient()
からいってもいいんだけど、途中でResteasyWebTarget
にキャストしなきゃいけなくなるのはダサい……
Apache CXFさん
ごめん、CXFのことはよく知らないんだ(なぜ書いた)。サイトを見る限り、JAX-RS2.0のClientAPIの他に2種類提供している模様。
Proxy-basedはRESTEasyのところで書いたのと同じ感じっぽい。これを残すのはかわる。 けれど、CXF WebClientAPIは標準のClientAPIとの差がわかりません。何か差別化できるところがあるんだろうか……。
まとめ
軽く使う分にはClient APIとしては標準のはそれなりに使いやすいし、特にはまりどころもなさそうな感じはする。 JAX-RS自体に慣れていないとProvider周りは困るだろうけど、それはそれ。
昔のバージョンから更新するときは、どの実装でも手作業で置き換えることになりそうだけど、標準に寄せるなら大したことしてないし、一から書き直しても知れているように思います。また、Proxyのを使ってるところはそのままで良いかなと。