jsr339-experts@jax-rs-spec.java.net

[jsr339-experts] Re: Updated Client API and Interceptors/Filters proposal is available - please review

From: Bill Burke <bburke_at_redhat.com>
Date: Tue, 07 Jun 2011 15:30:40 -0400

On 6/7/11 2:19 PM, Markus KARG wrote:
> Just a few notes I made while reading the samples in the WIKI.
>
>
> * As ResourceUri is not an URI but actually a factory for invocations, it might be better to stick with WebResource, or use a
>
> name like Endpoint or InvocationFactory. All those names make clear the "active" aspect of the class, while with ResourceUri
>
> everybody might be surprised that it is a factory actually.

A java.net.URI object is sort of a factory as well so I don't see your
point. But, I do agree that WebResource is a better name than ResourceUri.


What about Link or Href?



>
> * While I understand that technically ".perpareX()" is the correct method name, I assume that end users might like to use the
>
> simpler ".x()" instead (without "prepare"), as it is just so much shorter and better to read.


+1. Remove prepare from the method name. But, I don't want a builder
interface, nor do I want put() et. al. methods on WebResource.


>
> * From the view of the end user it is a bit verbose to write Client.create().request(). It would be very much more comfortable
>
> to just write Client.request(), since obviously a create() will use a default config anyways, so this could be implied by a
>
> direct Client.request() call. Only programmers wanting to share Client instances or wanting to use custom configs would have
>
> to write Client.create() then (which will be the minority I assume and such support CoC).

I really don't want Client to be a class. It should be an interface.

In my experience for unit tests Client.create().request() might be used
a lot if the unit test is only making one HTTP request, so you're right
on it being a tiny bit verbose.

But, I don't agree that that case is the majority of cases. Applications
and more complex unit tests will want to define their own Client
instance and re-use it. In a Java EE environment I could even see a
Client instance be injected with @Resource.

>
> * The filter example says a possible use of FilterAction.STOP could be a caching filter. Such a filter might need to not only
>
> stop the filter chain, but replace the actual uncoditional call by a conditional one. In what way could the filter API solve
>
> this?

A cache filter might turn a normal GET request into a conditional GET.
It might also just return a Response object without pinging the server.
  Please review the caching example that Santiago/Marek provided. Also,
my blog discusses in detail how and why things need to work the way they do.


>
> * The interceptor sample says a possible use of interceptors would be GZIP. As GZIP is a transparent but essential part of
>
> HTTP, I doubt that end users will understand that they must user interceptors to add GZIP. I think most would just expect that
>
> GZIP is handled transparently by the JAX RS engine or it's transport delegate. I do not think that people would love to see
>
> that they must handle GZIP again and again in every application they write. So the GZIP Interceptor should be a mandatory part
>
> of any JAX RS implementation.

Interceptors can be used to implement features for frameworks or for
applications. I'm sure there are other content encodings out there.
I'm sure that the constraints mobile puts on things there will be new
compression methods suggested.

That being said, there are different ways to trigger interceptors.
Resteasy's GZIP interceptor is automatically bound to client and server
request chains. If the Content-Encoding header is set to "gzip" then
the interceptor is triggered and it will compress (or uncompress) the
request or response entity. We have a different built-in interceptor
that can decorate the Content-Encoding header if an annotation or
property is set.

I disagree that gzip should be mandatory part of spec. Please, let's
not argue about it for 2 weeks.

>
> * The complexity of the current annotation based proposal for filters feels a bit overcomplicated. I am a big friend of annotations, aspects and all that, but it just so much simpler to write "Client.from(URL).filter(myFilter).post(entity)" than doing it the proposed way.
>

I think you're missing the fact that we want to use this interceptor
framework on the server side too. The idea here is that you are binding
behavior to an annotation. CDI has a similar concept.

On the server side (and this interceptor proposal would be used ont ehs
erthis is great because the annotation can have additional metadata that
the filter/interceptor is interested in.


For example, you could have a @Signed annotation that digital signs the
response.

@Signed(useCallerPrincipal=true)
public String getResource()
{
   return "hello";
}

Here the @Signed annotation triggers the binding of a
DigitalSignatureInterceptor which gets access to the @Signed annotation
and sees you want to use the caller principal to determine the private
key to use to sign the response.

Getting me?

-- 
Bill Burke
JBoss, a division of Red Hat
http://bill.burkecentral.com