Hi Dhanji,
Here are some additional comments in addition to my reply to Marc:
> This is a good approach, for the straightforward cases, one
> can use the raw types directly but for additional metadata
> the Representation<T> interface offers more flexibility.
I'm not against the concept of having a Representation artifact in an API,
we do have a Representation class in the Restlet API, but I don't think (ye)
that this is necessary in our higher-level JSR API.
Could you give me an example where the pure annotation approach wouldn't be
flexible enough to carry additional metadata?
> (iii)
>
> @UriTemplate("someuri")
> public class SomeBean {
> @HttpMethod
> Foo postData(Bar bar) {
> ...
> }
> }
>
> @Representation(mediaType="application/foo")
> public class Foo {
> ...
> }
>
> @Representation(mediaType="application/bar")
> public class Bar {
> ...
> }
>
>
> If this is the choice, then it we should also have the option
> to specify it on the service class (as in example (i))--as
> you point out marc, not all source code is under ones
> control. More importantly, the api should not force people to
> use only non-final classes or write delegate subclasses
> simply to serve as a metadata bridge.
I agree with you and believe that the combination of (iii) and (iv) solves
this issue.
> (iv)
>
> @UriTemplate("someuri")
> public class SomeBean {
> @HttpMethod
> @Representation(mediaType="application/foo")
> Foo
> postData(@Representation(mediaType="application/bar")Bar bar) {
> ...
> }
> }
>
> I prefer this approach because it is more flexible in terms
> of having multiple @HttpMethods returning consuming and
> different media types at the same resource name/template. In
> this way, I can reuse methods internally (consume both
> text/xhtml and text/xml for instance--and parse them with the
> same internal method).
Agreed.
> 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.
>
> Even if you were able to edit those classes, I would argue
> that they are the wrong place to annotate. The same entity
> may be consumed from a variety of different encodings, I
> should not have to create an adapter subclass for each one of
> those simply to specify the encoding. Also, it is the service
> that depends on the entity, not the other way around--so I
> dont see a reason for importing service-api classes (even
> annotations) in the entity .java. The entity is roughly a
> domain model class. It should not model anything but its
> target problem domain (fields and props of object being
> passed around).
If the POJO used as entity/representation doesn't know how to serialize
itself (pure domain POJOs), then it isn't useful to add annotations directly
to those classes. An external serialization service will be necessary. In
other cases where the POJO know how to serialize itself (with toString(),
toXML() and toJSON() methods for example), it might be interesting to
annotate the class directly. It could also be possible that the Resource
POJO itself knows how to expose its Representations (again, with toXML(),
toJSON() methods for example). The annotations should be flexible enough to
accommodate the various use cases, especially as we don't want to constraint
the annotated POJOs.
> I would say that this problem could also be solved like so:
>
> @HttpMethod
> public Entry postEntry(InputStream media, EntityMetadata metadata) {
> ...
> }
>
> With the understanding that the presence of the second
> parameter is entirely optional. I would even prever a more
> granular and flexible extension than a catchall Entity
> metadata wrapper:
>
> @HttpMethod
> public Entry postEntry(InputStream media, @RequestParameters
> Map<String, String[]> params, @Headers String[] headers) { //etc.
> ...
> }
>
> Which would let you choose from a set of predefined
> breakdowns of various granularity (@RequestContext
> HttpServletRequest?). This somewhat ameliorates the issue of
> having a too low-level api that I saw raised in an earlier
> thread (the welcome thread), as it lets the user pick and
> choose how low-level her service consumption api is.
I generally agree with your approach. I would prefer to specify dedicated
annotations for common metadata (media type, character set, encoding, last
modification date, expiration date, language, tag and size). For the rest of
the request/response data model, we could rely on a @Context annotation with
a parameter containing the name of the data to inject:
@Method
public void post(
@Input InputStream in,
@Context("serverInfo.address") String serverAddress,
@Context("serverInfo.userAgent") String userAgent){
...
}
We would just need to standardize the list of property names. This is very
similar to the approach used for custom log formats. Here is a complete list
of properties that we expose in a similar way in the Restlet API:
http://www.restlet.org/documentation/1.0/api/org/restlet/util/Template.html
> To sum up, I am for the Representation<T> as an optional
> return when warranted. But I feel that I have not clearly
> understood the purpose of Entity<T> (beyond the fact that it
> carries metadata--which I think can be addressed differently).
Personally, I don't see the need of either the Representation class or the
Entity interface in our JSR API.
Best regards,
Jerome