users@jax-rs-spec.java.net

[jax-rs-spec users] Re: JAX-RS Client Reactive API review

From: Santiago Pericasgeertsen <santiago.pericasgeertsen_at_oracle.com>
Date: Tue, 17 Jan 2017 10:38:23 -0500

> On Jan 13, 2017, at 6:30 PM, Ondrej Mihályi <ondrej.mihalyi_at_gmail.com> wrote:
>
> My counterproposal is to provide an additional RxClient class which always produces reactive invocations, and keep the normal Client untouched.
>
> I don't think this would be a clean solution. It would mean to duplicate every downstream interface to provide rx invocation builder after request() is called. Moreover, the current API clearly separates how the request is built from how it is invoked. I can only imagine an easy solution with a non-fluent API ( RxClient.request(webTarget) )

 We are not going to create new type of Client for Rx, in the same way we didn’t create one for Async. The amount of duplication and extra work is unwarranted.

— Santiago

>
> 2017-01-13 23:56 GMT+01:00 Markus KARG <markus_at_headcrashing.eu <mailto:markus_at_headcrashing.eu>>:
> Pavel,
>
>
>
> thank you for sharing the code examples.
>
>
>
> In fact I don't know if you actually want us to repeat our arguments, but here is my personal judgement of the proposed RX API:
>
>
>
> * The decision to make CompletableStage the default and most simple way to use RX in JAX-RS is appreciated, as it will never go away, due to de-facto being the sole RX interface in the Java world which is part of the JRE and / or any JCP standard currently and in near future.
>
>
>
> * I don't like the rx() method which changes from "synchronous" to "reactive" invocation. I doubt that anybody would love to repeat rx() again and again, and I doubt that people want to write programs that shares sync and rx style invocations within the same code block. My counterproposal is to provide an additional RxClient class which always produces reactive invocations, and keep the normal Client untouched.
>
>
>
> * I don't like the need to write down the type of custom RX invoker type again and again. I doubt that people really will write software which shares CompletableStage, RxJava, Guava etc. within the same code block. I assume that people instead will write full applications in *either* CompletableStage *or* RxJava *or* Guava etc (so they decide per app, not per invocation). The resulting application source code will be easier to read and potentially less error-prone if there instead would be an SPI to replace JAX-RS's reactive provider at deploy time, e. g. from the default CompletableStage to RxJava Observable.
>
>
>
> * The proposal only contains reactive support for the client API. I want to rise the question whether it might be a good idea to also extend server-sided async support at the same time. My proposal is to allow Future<T> as a return type of resource methods, so it is pretty easy to do concise async code like the example below (if we enforce CompletableFuture instead of CompletableStage). The idea is to get rid of the async boilerplate and the need to explicitly wait for the result of the RX invocation, but just to tell JAX-RS to set up the precessing chain and let it execute in the background by Java EE's default ManagedExecutorService (hence outside of the scop of the code block, hence outside the HTTP thread pool):
>
>
>
> @GET public Future<List<String>> collectResultsFromOtherServers() {
>
> return client.target("remote/forecast/{destination}")
> .resolveTemplate("destination", "mars")
> .request()
> .header("Rx-User", "Java8")
> .rx()
> .get(new GenericType<List<String>>() {
> });
> /*
> * Certainly the actual idea is to combine many parallel invocations instead of simple returning one!
> */
> }
>
>
>
> -Markus
>
>
>
>   <>
> From: Pavel Bucek [mailto:pavel.bucek_at_oracle.com <mailto:pavel.bucek_at_oracle.com>]
> Sent: Freitag, 13. Januar 2017 21:36
> To: jsr370-experts_at_jax-rs-spec.java.net <mailto:jsr370-experts_at_jax-rs-spec.java.net>
> Subject: JAX-RS Client Reactive API review
>
>
>
> Dear experts,
>
> please review following wiki and APIs:
>
> https://java.net/projects/jax-rs-spec/pages/RxClient <https://java.net/projects/jax-rs-spec/pages/RxClient>
> All added classes related to Reactive Client APIs are linked from that page, but let me allow a short recap.
>
> JAX-RS Client is being extended by the ability to provide a way how to process responses in reactive fashion. The change consists of:
>
> - adding rx(...) methods to Invocation.Builder
> - defining RxInvoker
> - allowing users to extend this API by providing RxInvokerProvider
>
> Specification will mandate implementation for CompletionStage from Java SE 8.
>
> Client code examples:
>
> - basic use
>
> CompletionStage<List<String>> cs =
> client.target("remote/forecast/{destination}")
> .resolveTemplate("destination", "mars")
> .request()
> .header("Rx-User", "Java8")
> .rx() // gets CompletionStageRxInvoker
> .get(new GenericType<List<String>>() {
> });
>
> cs.thenAccept(System.out::println);
>
> - using custom RxInvokerFactory (this is little artificial, since the factory just returns CompletionStageRxInvoker, but support for Observable from RxJava or ListenableFuture from Guava can be done in the exact same manner)
>
> CompletionStage<List<String>> cs =
> client.target("remote/forecast/{destination}")
> .resolveTemplate("destination", "mars")
> .request()
> .header("Rx-User", "Java8")
> .rx(CompletionStageRxInvokerProvider.class)
> .get(new GenericType<List<String>>() {
> });
>
> cs.thenAccept(System.out::println);
>
>
> Source links:
>
> - https://github.com/jax-rs/api/blob/2.1-m02/jaxrs-api/src/main/java/javax/ws/rs/client/Invocation.java#L298 <https://github.com/jax-rs/api/blob/2.1-m02/jaxrs-api/src/main/java/javax/ws/rs/client/Invocation.java#L298>
> - https://github.com/jax-rs/api/blob/2.1-m02/jaxrs-api/src/main/java/javax/ws/rs/client/RxInvoker.java <https://github.com/jax-rs/api/blob/2.1-m02/jaxrs-api/src/main/java/javax/ws/rs/client/RxInvoker.java>
> - https://github.com/jax-rs/api/blob/2.1-m02/jaxrs-api/src/main/java/javax/ws/rs/client/RxInvokerProvider.java <https://github.com/jax-rs/api/blob/2.1-m02/jaxrs-api/src/main/java/javax/ws/rs/client/RxInvokerProvider.java>
> Examples & tests:
>
> - https://github.com/jax-rs/api/blob/2.1-m02/jaxrs-api/src/test/java/javax/ws/rs/core/RxClientTest.java <https://github.com/jax-rs/api/blob/2.1-m02/jaxrs-api/src/test/java/javax/ws/rs/core/RxClientTest.java>
> - https://github.com/jersey/jersey/blob/2.x/core-client/src/test/java/org/glassfish/jersey/client/ClientRxTest.java#L86 <https://github.com/jersey/jersey/blob/2.x/core-client/src/test/java/org/glassfish/jersey/client/ClientRxTest.java#L86>
> The last link is to the Jersey repository. Jersey version 2.26 will be JAX-RS 2.1 RI and branch 2.x is where the development will happen. Jersey 2.26-b01 (which is being released right now) implements all rx(...) methods; feel free to test/evaluate it there.
>
> Looking forward to your feedback!
>
> Thanks and regards,
> Pavel
>
>
>
>
>