原文はこちら。
https://blogs.oracle.com/PavelBucek/entry/jax_rs_2_1_reactive
Marekに代わって、JAX-RSの共同Spec leadに選ばれたことを発表できうれしく思っています。ってわけで、この先数ヶ月間、おおよそJavaOne 2017までの間に関するエントリを記載します。
様々な仕様における議論をフォローしているのであれば、昨年のJAX-RSの議論は非常に閑散としたものだったことにお気づきかもしれません。しかし、変わりつつあります。いや、既に変わりました。Expert Group (EG) はアップデートされたスケジュールで、主として以下の3件について作業をしています。
簡単な例を見てみましょう。
変更される可能性があるため、詳細に入ることは避けますが、現時点では、これが拡張性の提供に関する最善の方法であるとの結論に達したようです。議論の経緯を知りたい方は、JAX-RS仕様のExpert Groupメーリングリストをご覧ください。
新たに提案されたAPIを気に入ってもらえることを願っています。何かコメントがありましたら、JAX-RSプロジェクトのユーザーメーリングリストに投稿してください。
https://blogs.oracle.com/PavelBucek/entry/jax_rs_2_1_reactive
Marekに代わって、JAX-RSの共同Spec leadに選ばれたことを発表できうれしく思っています。ってわけで、この先数ヶ月間、おおよそJavaOne 2017までの間に関するエントリを記載します。
様々な仕様における議論をフォローしているのであれば、昨年のJAX-RSの議論は非常に閑散としたものだったことにお気づきかもしれません。しかし、変わりつつあります。いや、既に変わりました。Expert Group (EG) はアップデートされたスケジュールで、主として以下の3件について作業をしています。
- Reactive Client API
- Server Sent Events
- Non-blocking I/O
JAX-RS Reactive Client API
まず、この機能の目的は、クライアント側でのリアクティブスタイルのプログラミングのサポートを含めることであって、それ以外のことはありません。また、別のクライアントを作成したくはありません。既存のものは既に同期および非同期のリクエスト実行をサポートしており、これをリアクションスタイルで拡張したいと考えています。簡単な例を見てみましょう。
何か新しいものがあることに気付かれたことでしょう。戻り型がjavax.ws.rs.Responseでも、(rx()がasync()に置き換えられた場合には)Future <Response>でもなく、Client fluent API呼び出しチェーンにある新しいメソッド、rx()です。CompletionStage<Response> csResponse = ClientBuilder.newClient()
.target("http://oracle.com")
.request()
.rx()
.get();
javax.ws.rs.ResponseCompletionStageは、Java 8で導入された新しいインターフェースです。これはプラットフォームに組み込まれた唯一のリアクティブ標準です(詳細は後で)。今回、rx() メソッドが追加されたことにより、SyncInvoker/AsyncInvokerから、新しいRxInvokerに切り替えることができるようになりました。
http://docs.oracle.com/javaee/7/api/javax/ws/rs/core/Response.html
Interface SyncInvokerRxInvokerは他のメソッドと同じメソッドを定義しますが、同じ方法で指定された戻り値の型は持ちません。CompletionStageRxInvokerという、現在提案中のAPIで実施しているように、CompletionStageに対してサブクラスを作成し、再定義することができます。
https://docs.oracle.com/javaee/7/api/javax/ws/rs/client/SyncInvoker.html
Interface AsyncInvoker
https://docs.oracle.com/javaee/7/api/javax/ws/rs/client/AsyncInvoker.html
CompletionStageRxInvoker.javarx() メソッドにはいくつかのバリエーションがあります。1つはExecutorServiceの提供に関連し、もう1つはRxInvokerクラスの提供に関するものです。
https://github.com/jax-rs/api/blob/master/jaxrs-api/src/main/java/javax/ws/rs/client/CompletionStageRxInvoker.java
ExecutorService前者は簡単に説明ができます。つまり、リアクティブな呼び出しは本質的に非同期であって、スレッドプールやExecutorServiceを指定できるようにしたい、ということです(例えば、後で再度呼び出されたり、クライアント全体にわたる非同期executorサービス構成を許可することによって削除されたりする可能性があります)。後者は拡張性に関するものです。
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html
Reactive Extensions
リアクティブなアプリケーションをJavaで実装する場合、さまざまなフレームワークが提供する他のデータ型を知っていることがほとんどでしょう。Guava、RxJavaなどといった、これらのフレームワークは、CompletionStageと同様の機能を提供しますが、APIが異なります。特に、他の非標準フレームワークを使って作成されたアプリケーションを有していて、JAX-RSができるだけ簡単に使用できるようにしたい場合は、これらを使用すると便利です。 コード例を見てみましょう。ここで、JAX-RSのResponseを取得する際に、RxJava2のFlowableを利用できることがわかります。Client client = ClientBuilder.newClient();
client.register(FlowableProvider.class);
Flowable<Response> csResponse = client.target("http://oracle.com")
.request()
.rx(FlowableInvoker.class)
.get();
FlowableFlowableProvider、FlowableInvokerとも、第三者が提供しています。たとえば、RxJava2の開発者コミュニティのJAX-RSが十分に重要と考える場合、これらのクラスを含む拡張モジュールがリリースされる可能性があります。また、いつものように、任意のJAX-RS実装は機能を選択でき、同様のプロバイダを実装の一部として提供することができます。
http://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Flowable.html
変更される可能性があるため、詳細に入ることは避けますが、現時点では、これが拡張性の提供に関する最善の方法であるとの結論に達したようです。議論の経緯を知りたい方は、JAX-RS仕様のExpert Groupメーリングリストをご覧ください。
新たに提案されたAPIを気に入ってもらえることを願っています。何かコメントがありましたら、JAX-RSプロジェクトのユーザーメーリングリストに投稿してください。
Links, mailing lists, etc.
- JAX-RS JCPのページ
https://jcp.org/en/jsr/detail?id=370 - JAX-RS Expert Groupメーリングリストのアーカイブ
https://java.net/projects/jax-rs-spec/lists/jsr370-experts/archive - JAX-RSユーザーメーリングリスト
users [at] jax-rs-spec.java.net
https://java.net/projects/jax-rs-spec/lists/users/archive - JAX-RSソースリポジトリ(GitHubのミラー)
https://github.com/jax-rs/api