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

From: Pavel Bucek <>
Date: Mon, 16 Jan 2017 12:56:00 +0100

now I'm confused and I don't really know where should I answer :)

please see inline.

<snip />
>>> 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> ?

I still believe that these extensions shouldn't lock you into specific
JAX-RS implementation.

If I'm not mistaken, users don't write Jersey APPs, they do write JAX-RS
apps, which are then deployed to some application server. Why would he
need to care which implementation is underneath? (of course, there might
be impl-specific feature, but then you are simply not portable anymore

I believe that having this as a portable extension by design is step to
more portable applications and consequently better usability.

>>>> 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.
>> 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.

Is it "Jersey users" or "Glassfish/WebLogic users"?

I know that usually implementation brings some features to be
competitive etc, but also those features can be then included in the
spec itself, so users don't need to depend on them any more and regain
the portability again. This is happening in this case (as Jersey already
has similar api implemented for couple of years and I believe others as
well). If we keep this extension forcibly implementation specific, we
are not gaining much.

As I said, ideally there is rxjava provided module for dealing with
that. Or some expert can create that as his project. Or it can even be
part of any of JAX-RS implementation.

>>> .rx(CompletionStage.class)
>>> 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
> .rx(CompletionStageRxInvokerProvider.class)
> returns, RxInvoker<CompletionStage> ?

if you look here:

you'll see that it now returns "T ? extends RxInvoker"

It should be possible to downgrade it to plain RxInvoker<T>. Also, we
should be able to remove CompletionStageRxInvoker from the API if that

> 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

I appreciate your comments and proposals. That's what we all trying to
do - I hope I don't "sound" so defensive or something like that, I'm
really trying to understand and evaluate other proposals. It's always
better to have a discussion than end up with "accepted after 2 weeks of
radio silence" :)

Thanks and regards,

> Cheers, Sergey
>> Best regards,
>> Pavel
>>> 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 []
>>>>>> *Sent:* Samstag, 14. Januar 2017 12:54
>>>>>> *To:*
>>>>>> *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).
>>>>>> Ondrej