[jax-rs-spec users] Re: Suggestion to refactor rx invoker API

From: Sergey Beryozkin <>
Date: Mon, 16 Jan 2017 10:55:46 +0000

Hi, see inline,
On 16/01/17 10:48, Pavel Bucek wrote:

Hi Sergey,

please see inline.

On 16/01/2017 11:11, Sergey Beryozkin wrote:
Pavel, see comments below
On 15/01/17 18:15, Pavel Bucek wrote:


thanks for the proposal. I will look into it later, now I just want to react to some things which are already being discussed here..

Sergey, Markus, thanks for evaluating Ondrejs proposal.

Please see inline.

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 ?

I'm not an oracle (haha) to know the future, I hope it will happen in some form. Or someone else, not related to rxjava could do it, it might become popular and JAX-RS users would include it in their projects.

Anyway, if there is a question on Jersey user list and Jersey doesn't provide it (and I know about 3rd party compatible extension), I have no issue with recommending that.
Yes for some cases that will work, but the users will expect something from the favorite project, right :-) ? Say, RxInvoker<Observable> ?

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


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,


will introduce a CXF/etc package into the code.

and where is the problem? Do you expect that module with rx invoker provider, which is part of CXF, won't work when used with other implementation? If the interface implementation is written properly and there are no casts to implementation specific classes, it shouldn't matter.

Jersey users would def hate import a CXF/RestEasy package, similarly for CXF/RestEasy. We'd like our implementations be as complete as possible.


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

Mine issue with this is that you usually dont want to do rx(CompletionStage.class). You most likely want rx(CompletionStage<List<String>>.class), which is not valid Java syntax. And I must admit I don't like GenericType and I'll be always trying to find an alternative which won't force that.

I thought .rx(CompletionStage.class)

will return what


returns, RxInvoker<CompletionStage> ?

As I implied in the other thread (though I'm fine continuing here if it works) I'm more or less ok with what you suggested - that would be straightforward, but I'm still wondering if

.rx(CompletionStage.class) works and if it does then how this method will be implemented

Cheers, Sergey

Best regards,

Thanks, Sergey
Thanks and regards,


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)". :-)


From: Ondrej Mihályi [<>]
Sent: Samstag, 14. Januar 2017 12:54
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<> (although not using JAX-RS, just wrapping a method that returns a CompletionStage).