users@jax-rs-spec.java.net

[jax-rs-spec users] How to register RX providers

From: Sergey Beryozkin <sberyozkin_at_talend.com>
Date: Mon, 16 Jan 2017 10:21:38 +0000

Hi All, thought I'd start a new thread in order to avoid overloading,

On 15/01/2017 17:20, Sergey Beryozkin wrote:
IMHO rx() needs to remain in order to get the default, this is as simple as it can get. Doing more than rx() in order to get CompletionStage would be bad.

But I'm warming to something similar to what you are suggesting. .unwrap() is redundant IMHO.

either rx() for the default

or, example,

RxInvoker<Observable> rxInvoker = rx(Observable.class)

The reason it works better than the prototype suggested by Pavel is that this code is *portable*.

Clearly, in most cases, it won't be the users who will create RxInvoker<Observable>, etc but Jersey, CXF, RestEasy will have dedicated modules with META-INF linking, in this case, Observable to a specific RxInvoker. This will be documented and users willing to work with non-default rx() will add a given module to the classpath...
Ideally, RxInvoker<Observable> is not created by Jersey nor CXF nor RestEasy, but by 3rd party library, which works on ALL JAX-RS implementations. Ideally RxJava itself could provide RxInvokerFactory (or however that will end up named).


It won't happen, ideally may be, but it won't - why would one host such a library and then maintain and release it ? At least the JAX-RS 2.1 projects will do and it will guarantee the users these libraries are in good shape. Someone can decide to do such a library but would you recommend Jersey users wait till it happens ?

That would allow the real portability, since you won't need to care about which implementation is underneath and which features does it provide. It will just work everywhere.

I don't understand. In your proposal we have


.rx(CompletionStageRxInvokerProvider.class)



Users will want to use something like that, ex, after JAX-RS 2.1 final is out, (for RxJava for ex), immediately. So are you saying they will have to wait for some kind of a market place to appear where these libraries will be made available but would be implementers ?
Even it it will happen, JAX-RS 2.1 projects will def ship their own implementations, CXF will def do it. And here is my point,


.rx(CompletionStageRxInvokerProvider.class)


will introduce a CXF/etc package into the code.

.rx(CompletionStage.class)

will work with whatever library the users will choose, from Jersey, some 3rd party library, etc

Thanks, Sergey
Thanks and regards,
Pavel


Sergey


On 14/01/17 14:28, Markus KARG wrote:
Sounds good for me, but actually I think it would be even simpler if we name it "unwrap()", and do not fill in any parameters. As I said, I think applications will typically use only one technology at the time. So "unwrap()" simply can check if there is a @Provider registered having a method with the same parameters as your proposed "conver()", we finally have the requested plugability, no additonal complexity, follow existing JAX-RS patterns, and get rid of repeating lots of "rx(Class)". :-)

-Markus


From: Ondrej Mihályi [<mailto:ondrej.mihalyi_at_gmail.com>mailto:ondrej.mihalyi_at_gmail.com]
Sent: Samstag, 14. Januar 2017 12:54
To: jsr370-experts_at_jax-rs-spec.java.net<mailto:jsr370-experts_at_jax-rs-spec.java.net>
Subject: Suggestion to refactor rx invoker API

I was thinking about an alternative to current rx API, to simplify it in context of supporting extensibility.
My idea is to modify the CompletionStageRxInvoker, so that it returns an extension to CompletionStage, which would contain additional method to convert the interface to any other reactive interface:

public interface RxCompletionStage<T> extends CompletionStage<T> {
    <NEW> NEW convert(Function<CompletionStage<T>, NEW> converter);
}
With this, we would move all the complexity to this new interface, which still can be used as a usual CompletionStage, but with the additional convert method, it provides an extension point to other interfaces. And it's based on standard CompletionStage, therefore we don't need additional rx invokers.
We could remove RxInvokerProvider, the 2 rx() methods from the Builder, which accept RxInvokerProvider, and even remove the RxInvoker interface, as CompletionStageRxInvoker would be the only required implementation.

Here is an example of what I mean, with RxJava2 as an example:

client.request().rx().get(). // we get the RxCompletionStage here, which extends CompletionStage
    .convert(this::flowableFromStage) // accepts a function that converts the CompletionStage to another interface
    .subscribe(s -> testResult = s, Throwable::printStackTrace);

An example of a working code here<https://github.com/OndrejM-demonstrations/JavaEEReactive/blob/rxjava/src/test/java/reactivejavaee/CompletionStageRxJavaTest.java#L120> (although not using JAX-RS, just wrapping a method that returns a CompletionStage).

Ondrej