Of course, having first-class support for client proxies (like MP has done,
thank goodness) in the JAX-RS spec is key to this whole thing.
On Wed, Dec 26, 2018 at 5:50 PM James Carman <[email protected]>
wrote:

> Well, you can’t ignore the AsyncResponse either, because something has to
> hold the returned value. Those async methods are void. The cleanest
> solution would be for JAX-RS to formally support different async/reactive
> types as returns with some sort of @Provider. This would be kind of a
> hybrid between a MessageBodyReader and the RxInvoker stuff. You’d likely
> need support for both single and stream types. Perhaps the
> MessageBodyReader is the right answer, but it seemed odd since it won’t be
> called until the response is received, which is too late for truly
> asynchronous stuff.
>
> Maybe my usage is just odd, but it sure does make our microservices work
> simpler in a JVM-to-JVM scenario by having that shared API interface the
> server and client can both use. The JAX-RS spec seems really close, but a
> bit all over the place here (AsyncResponse, AsyncInvoker, RxInvoker, oh
> my).
>
> For our usage, we are only really focused on the response bodies. Non-2xx
> status codes yield an exception with CXFs ResponseExceptionMapper when
> using the client proxies for non-Response return types.
>
> Of course, maybe I just don’t understand this stuff at all and have just
> stumbled upon something that seemingly works, but might be ill-advised.
> On Wed, Dec 26, 2018 at 5:32 PM Andy McCright <[email protected]>
> wrote:
>
>> Thanks for the feedback.  I'll suggest that the next version of MP Rest
>> Client should ignore AsyncResponse parameters.  That way, a client app
>> could pass null for that argument, and everything should still work. It is
>> still a little "hacky", but I think the best solution is to use a separate
>> interface for the client than the server (though I agree that there is
>> some
>> convenience in using the same interface for both).
>>
>> As for returning Response objects vs strongly typed objects, I don't think
>> there is a recommendation either way.  Both work - it will depend on the
>> use case (like whether you need more information that what is in the
>> response body - i.e. do you need to know the response code?  or any of the
>> header values? etc.).
>>
>> Thanks,
>>
>> Andy
>>
>> On Wed, Dec 26, 2018 at 4:14 PM James Carman <[email protected]>
>> wrote:
>>
>> > Hmmmm, we have been using the same interface on both the server and
>> client.
>> > We publish an API jar (a separately-maintained artifact) for our
>> callers to
>> > use to talk to us and it makes interoperability a snap. This is using
>> just
>> > the CXF-specific stuff, but this AsyncRespone problem has plagued us,
>> so I
>> > was just curious if MP had solved it. If we could use
>> CompletionStage<T> on
>> > both the server and client, that’d be great. I’ve implemented that with
>> a
>> > MessageBodyWriter in the past, but wasn’t terribly happy with it. It
>> > worked, but felt sort of “hacky”.
>> >
>> > I’m also not a big fan of using Response objects as the return type,
>> since
>> > it doesn’t help folks understand what’s going on as much as
>> strongly-typed
>> > responses. Is that the suggested pattern to use for MP folks?
>> > On Wed, Dec 26, 2018 at 4:56 PM Andy McCright <
>> [email protected]
>> > >
>> > wrote:
>> >
>> > > Hi James,
>> > >
>> > > The client shouldn't know or care whether the service method is async
>> or
>> > > not - in fact, it shouldn't care whether the remote service is using
>> > JAX-RS
>> > > or even Java at all.
>> > >
>> > > So whether you have a JAX-RS service method that looks like this:
>> > > @Path("/mypath")
>> > > public class MyResource {
>> > >
>> > >     @POST
>> > >     @Path("sync")
>> > >     public Response postSync(MyEntity entity) { // do something
>> > > synchronously ... }
>> > >
>> > > //  or this:
>> > >
>> > >     @POST
>> > >     @Path("async")
>> > >     public void postAsync(@Suspended AsyncResponse ar, MyEntity
>> entity) {
>> > > // return something via async response ... }
>> > > }
>> > >
>> > > your MP Rest Client interface should look like this:
>> > >
>> > > @Path("/mypath")
>> > > public interface MyClient {
>> > >
>> > >     @POST
>> > >     @Path("sync")
>> > >     public Response postSync(MyEntity entity);
>> > >
>> > >     @POST
>> > >     @Path("async")
>> > >     public Response postAsync(MyEntity entity);
>> > > }
>> > >
>> > > Notice that the return type is the same in both cases - and that the
>> > > signature on the client methods do not include an AsyncResponse
>> argument.
>> > >
>> > > Keep in mind that in both cases, only the server is running
>> > > asynchronously.  The client will block for both methods.  IMO, this is
>> > less
>> > > valuable than using async on the client.  I don't really see much
>> point
>> > in
>> > > using async on the server unless your thread pool for handling JAX-RS
>> > > service methods is severely constrained.  But I think async on the
>> client
>> > > makes a lot more sense.  To do that, you would need to use MP Rest
>> Client
>> > > 1.1 (1.0 doesn't have async support), and then the client method
>> should
>> > > return an instance of CompletionStage.  So if you were to convert the
>> > > client above to run async, it would look like this:
>> > >
>> > > @Path("/mypath")
>> > > public interface MyClient {
>> > >
>> > >     @POST
>> > >     @Path("sync")
>> > >     public CompletionStage<Response> postSync(MyEntity entity);
>> > >
>> > >     @POST
>> > >     @Path("async")
>> > >     public CompletionStage<Response> postAsync(MyEntity entity);
>> > > }
>> > >
>> > > Hope this helps,
>> > >
>> > > Andy
>> > >
>> > >
>> > > On Sat, Dec 22, 2018 at 10:24 AM James Carman <
>> > [email protected]>
>> > > wrote:
>> > >
>> > > > With the Microprofile client support, what happens if I have an
>> async
>> > > > service method (with @Suspended and what not)?  How would I call it
>> > using
>> > > > the proxy object?
>> > > >
>> > >
>> >
>>
>

Reply via email to