On Apr 10, 2007, at 4:51 AM, Jerome Louvel wrote:
>
> Actually, I was proposing a combination of (iii) and (iv). If you
> don't have
> control on the source code of the representation classes, it should be
> possible to annotate them externally, either at the return type or
> parameter
> type level, or via an external annotation file (similar to JAXB
> approach).
>
OK, thanks for clarifying that.
>> Now for some additional comments:
>>
>> Approach (iii) would work well for custom types where the developer
>> has access to the source code and where the type has only one media
>> type. It doesn't work when the types being used are from an external
>> library or where the same type could be serialized using a
>> variety of
>> media types. E.g. consider the following variant of (i) above where
>> both the input and output are Strings:
>>
>> @UriTemplate("someuri")
>> @ProduceMime("application/foo")
>> @ConsumeMime("application/bar")
>> public class SomeBean {
>> @HttpMethod
>> String postData(String bar) {
>> ...
>> }
>> }
>>
>> To use approach (iii) the developer would have to write two
>> subclasses of String just to have something to attach the
>> @Representation to.
>
> Beside, my suggestion to rely on (iv) in this case, it is also
> important to
> note that it unlikely that you would want to expose POJOs as
> RESTful Web
> services if you don't even have control on the source case.
There's a difference between the POJO that forms the resource and the
class you use for representations. I think its entirely reasonable
that the methods of a POJO will work with things like String and
InputStream and you can't directly annotate either of those.
>
>> Approach (iii) also fails when the Java class is auto generated as
>> part of the build. E.g. when working with JAXB its common to
>> generate
>> the JAXB classes from the schema during the build process.
>> That means
>> you can't edit the generated classes to add the @Representation
>> annotation and the developer is again left having to write a
>> subclass
>> to attach the annotation to.
>
> Note that I consider the usage of JAXB to serialize representations
> as an
> important use case. But if you autogenerate your POJOs from an XSD
> schema,
> then it is unlikely that your POJOs will expose media types other
> than XML
> ones, otherwise you would need to have control on them to generate
> them
> (JSON for example).
That is true but there are many application/*+xml media types and
other attributes like language to consider.
> BTW, JAXB can also work using POJOs as an input instead
> of an XSD schema.
>
Thanks, I'm aware of that, I explicitly said "when the Java class is
auto generated" - i.e. my comment related to the starting with a
schema use case.
>> Approach (iv) is actually quite similar to approach (i), it just
>> moves the annotations and uses the same annotation for input and
>> output data. Approaches (i) and (iv) have very similar
>> properties and
>> both work well when the media types are known and are static. I'd
>> argue that (i) is better since it allows a developer to specify the
>> input and output media types once at the class level rather than on
>> every method but that is a relatively small point.
>
> We could perfectly extend (iv) to support the definition of default
> input
> and output representation metadata:
>
> @ParentRef("someuri")
> @Input("application/bar")
> @Output(mediaType="application/foo", characterSet="UTF-8")
> public class SomeBean {
> @Method
> Foo postData(Bar bar) {
> ...
> }
> }
>
It looks like we are very close to @ConsumeMime and @ProduceMime with
different names. BTW, I'm fine with a name change and also switching
the @ConsumeMime successor to be a class and parameter annotation
rather than a class and method annotation.
>> Where the pure
>> annotation approach falls down is in dealing with non-static types,
>> e.g. consider a method to add an Atom media entry:
>>
>> @UriTemplate("{feed}")
>> @ProduceMime("application/atom+xml")
>> public class AtomFeed {
>>
>> @HttpMethod
>> public Entry postEntry(Entity<InputStream> media) {
>> ...
>> }
>>
>> ...
>> }
>>
>> The above is similar to approach (ii) above except the ConsumeMime
>> annotation has been removed so the method will be called for any
>> media type. Here the media method parameter contains an input stream
>> from which to read the entity body and additional metadata including
>> the media type and language. Without the Entity class the developer
>> would either have to create a new class to do the same job
>> along with
>> a serializer and deserializer for that class or use a low level API
>> to extract the Content-Type (and possibly other) header from the
>> request. The same problems occur when a method needs to return
>> something where the metadata isn't known in advance. I think these
>> are common enough use cases that its worthwhile standardizing the
>> Entity interface and Representation class to save developers the
>> additional effort their omission would cause.
>
> I agree that this is an important case to consider. There are
> annotation
> based solution like:
>
> @Method
> public Entry postEntry(@Input InputStream data, @MediaType String
> type) {
>
There's already a general purpose @HeaderParam("Content-Type") that
could be used instead of a specific @MediaType annotation.
Marc.
---
Marc Hadley <marc.hadley at sun.com>
CTO Office, Sun Microsystems.
- application/pkcs7-signature attachment: smime.p7s