users@jax-rs-spec.java.net

[jax-rs-spec users] Re: JAX-RS 2.1 - work schedule

From: Pavel Bucek <pavel.bucek_at_oracle.com>
Date: Wed, 18 Jan 2017 10:54:51 +0100

Alright :)

After having a chat with Santiago, I tried to prototype "real provider"
approach, which would result in code like:

Client rxClient =client.register(CompletionStageRxInvokerProvider.class);

CompletionStage<UserPojo> cs =
         rxClient.target("http://foo.bar")
                 .request()
                 .rx(CompletionStage.class)
                 .get(UserPojo.class);

(let's not talk about built-in support for CompletionStage and consider
this as a valid extension, provided by CompletionStageRxInvokerProvider
registered to the client).

The major change here is the "rx" method signature, which would be:

public interface Invocation {
// ...

public static interface Builderextends SyncInvoker {

        // ...

public <T> RxInvoker<T> rx(Class<T> clazz);
     }
}

The major change here is the return type. It is no longerT ? extends
RxInvoker, it is RxInvoker<T>. And that brings and issue I don't know
how to deal with. To be able to do the example code (first code
snippet), we'd need something like:

public interface RxInvoker<T> {

// ...

public <R>T<R> get(Class<R> responseType);

}

Problem is that this is not a valid Java syntax. We simply cannot do
T<R>. Let's compare that to previous proposal:

public interface Invocation {
// ...public static interface Builderextends SyncInvoker {

        // ...public <T extends RxInvoker>T rx(Class<?extends RxInvokerProvider<T>> clazz);

     }
}

public interface RxInvoker<T> {

// ...public <R>T get(GenericType<R> responseType);

}

The main difference (and the reason why it works) is the return type if
Invocation.Builder#rx(..) is an instance of subclass of RxInvoker, not
of a RxInvoker<T>. That allows to override return type of
RxInvoker#get(..) method, exactly as it is done in
CompletionStageRxInvoker:

public interface CompletionStageRxInvokerextends RxInvoker<CompletionStage> {

// ...
     @Override public <T> CompletionStage<T> get(Class<T> responseType);

}

Does anyone know how to solve this issue? (because if not, I don't see
how we can design/support "real provider" case). I'm looking forward to
any comments. If you want to play with latest change, feel free to clone
[1], the example is [2], Invocation.Builder#rx [3] and RxInvoker [4].
Thanks and regards, Pavel [1] https://github.com/pavelbucek/jax-rs [2]
https://github.com/pavelbucek/jax-rs/blob/rx-client/jaxrs-api/src/test/java/javax/ws/rs/core/RxClientTest.java#L110
[3]
https://github.com/pavelbucek/jax-rs/blob/rx-client/jaxrs-api/src/main/java/javax/ws/rs/client/Invocation.java#L338
[4]
https://github.com/pavelbucek/jax-rs/blob/rx-client/jaxrs-api/src/main/java/javax/ws/rs/client/RxInvoker.java#L86

On 17/01/2017 17:41, Ondrej Mihályi wrote:
> +1
> ||
> 2017-01-17 16:57 GMT+01:00 Santiago Pericasgeertsen
> <santiago.pericasgeertsen_at_oracle.com
> <mailto:santiago.pericasgeertsen_at_oracle.com>>:
>
>> On Jan 13, 2017, at 6:19 PM, Ondrej Mihályi
>> <ondrej.mihalyi_at_gmail.com <mailto:ondrej.mihalyi_at_gmail.com>> wrote:
>> Actually, I like the unwrap method more than the current
>> proposal. It makes it explicit what I want to get when I write
>> code. The current proposal is similar, but requires me to
>> remember the name of the invoker on top of the rx interface I
>> want to get.
>> Compare:
>> _Current proposal _
>> CompletionStage<List<String>> cs = client.request()
>> .rx(CompletionStageRxInvokerProvider.class)
>> .get(new GenericType<List<String>>() {
>> });
> Perhaps we should explore turning this into a "real provider”.
> I.e., something that is registered in the runtime and looked up by
> the JAX-RS implementation. In which case, the param to rx() could
> be CompletionStage.class instead. This would be more inline with,
> say, ParamConverters.
> — Santiago
>