dev@jsr311.java.net

RE: _at_Representation

From: Jerome Louvel <jerome.louvel_at_noelios.com>
Date: Thu, 26 Apr 2007 16:18:21 +0200

Hi Marc,

[...]

> (i) Marking a resource method
>
> @Representation
> public Client getClient() {}
>
> public void put(@Representation Client client) {}
>
> public void delete()
>
> vs
>
> @HttpMethod
> public Client getClient() {}
>
> @HttpMethod
> public void put(Client client) {}
>
> @HttpMethod
> public void delete()
>
> Since @Representation doesn't appear on the delete method its not
> clear that it is really being used to mark a resource method or
> whether the name of the resource method alone determines whether it
> is exposed. I think the latter is dangerous since it can easily lead
> to unforeseen consequences when an existing class method matches the
> naming pattern. get in particular is a popular method prefix as is
> put. I much prefer explicit marking as per @HttpMethod (though I'm
> open to a name change as has been suggested).

This assumption is based on the fact that all the resource POJOs will be
developped with the annotations in mind. As long as a POJO is marked as a
resource (via the @ResourceRef annotation), we can impose a match between
the Java method name and the HTTP method name. This is a refreshing
simplification. The method name would have to match exactly the HTTP method
name, therefore deleteCustomer() would not match.

The GET method is a special case method. There would be no direct handling
like for post(), put() or delete(). It is useful to take into account the
content negotation and caching. By default, no get() method would be
necessary but the presence of a @Representation annotation on a get*()
method would expose one set of representation for the current resource. You
could have on the same resource class:

        @Representation
        Customer getCustomer(){...}

        @Representation
        Document getCustomerAsXml(){...}

        @Representation(mediaType="application/xml")
        InputStream toXml(){...}

> (ii) Mark a method parameter corresponding to a request entity
>
> public void put(@Representation Client client)
>
> vs
>
> public void put(Client client) {}
>
> The @Representation annotation doesn't seem to add much here. In the
> sketch2 API, a resource method may have zero or one method parameter
> that isn't annotated and that parameter corresponds to the request
> entity.

True, we could support this simplification. @Representation could be useful
in other cases like:

        public void put(@Representation(mediaType="application/xml")
                            InputStream in){
           ...
        }

> (iii) Provide metadata for the entity returned by a method
>
> The default values could cause problems. There no way (AFAICT) when
> using reflection to determine whether an annotation property
> value is
> specified or is being defaulted. This means, e.g. that
>
> @Representation
> public Client getClient() {}
>
> is equivalent to:
>
> @Representation(mediaType="application/octet-stream", language="en",
> characterSet="UTF-8" encoding="identity")
> public Client getClient() {}
>
> If (i) above is an intended usage then I'd suggest making the
> defaults be "" since otherwise the presence of @Resource will
> fix the metadata values in addition to marking the method.

Sure, that makes sense.
 
> Note that in the sketch2 API a single valued @ProduceMime annotation
> will perform the same function for the media type of a response.

OK.
 
> (iv) Provide conneg data for the entities in a request and response
>
> In the sketch2 API, @ProduceMime and @ConsumeMime each
> provide a list
> of media types that can be generated and consumed by a method.
> @Representation is single valued so you can't easily write a method
> that e.g. accepts multiple formats. There also doesn't appear to be
> any way to use @Representation at the class level for a number of
> methods with similar properties - at a minimum you'd need separate
> properties or annotations for request and response I'd think.

You could use patterns like @Representation(mediaType="application/*"), or
even allow a list of comma separated values (similar to the Accept header).

I'm not convinced abou the need to have defaults at the class level. If this
becomes a real issue we can always separate the @Representation annotation
into two similar @Input and @Output annotations. We are closer to the
@ProduceMime, @ConsumeMime annotations but consider all the metadata instead
of just the media type. Accepting only certain languages for example is
important.
 
> I'd be interested to hear whether folks think that its important to
> provide automatic conneg support for language, charset and encoding ?

+1 for me (obviously)

Best regards,
Jerome