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