users@jax-rs-spec.java.net

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

From: Sergey Beryozkin <sberyozkin_at_talend.com>
Date: Mon, 16 Jan 2017 12:22:00 +0000

Hi Pavel, np, thanks for trying to address all of my comments

Only one clarification,

"Jersey users would def hate import a CXF/RestEasy package, similarly
for CXF/RestEasy."

Say if we have CXF users, they'd prefer

to import a given RxInvoker impl with a cxf package. I've just checked
our m01 based code and RxInvoker Observable impl is CXF specific so I'm
getting your point too...

Anyway, I'll play with a 2.1-m02 in the next few days and let you know
how it all fits for us

Thanks, Sergey


On 16/01/17 11:56, Pavel Bucek wrote:
>
> 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 anyway).
>
> 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:
>
> https://github.com/jax-rs/api/blob/master/jaxrs-api/src/main/java/javax/ws/rs/client/Invocation.java#L325
>
> 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
> happens.
>
>> 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,
> Pavel
>
>>
>> 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 [mailto:ondrej.mihalyi_at_gmail.com]
>>>>>>> *Sent:* Samstag, 14. Januar 2017 12:54
>>>>>>> *To:* 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
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>