Thanks Jerome, that helped a lot.
I still need a few clarifications, though:
> > So far so good, but what about POSTs? Should the constructor
> > check the
> > method type, like so:
> >
> > public MyBeanResource(Context context, Request request,
> > Response response){
> > super(context,request,response);
> > if (request.getMethod().equals(Method.GET)) {
> > String name = request.getResourceRef().getLastSegment();
> > myBean = new MyBean(name);
> > } else {
> > // it's a POST - nothing to do.
> > }
> > }
> > This doesn't sound right.
>
> Indeed this would be confusing. The method-based dispatching in the
> responsability of the caller, not the resource itself. Once the
> MyBeanResource instance is created, the Finder will introspect it to find
> the matching handle*() method based on the method name. Most of the common
> methods already have an implementation of handle*() on the base Resource
> class.
My question was more 'what the constructor should do for a PUT request?'
For a GET, it builds the resource (from the DB, filesystem, etc.) based on the
URI. But this doesn't apply to a POST or a PUT. The constructor doesn't know
the finder is building a MyResource instance to answer a PUT.
In the ch7 examples, UserResource's constructor behaves like all methods were
GETs: it always attempts to retrieve the username from the URI and -if it's not
null- it gets it from the DB. If the request is a PUT, it should not even
attempt to retrieve the resource, as it doesn't exist
yet. How can the constructor decide what to do?
> > But, how do I have access to the client's preferred variant
> > (application/xml in
> > this case)?
>
> This is done automatically for you in the Resource.handleGet() method.
Oh, so if I want to return a representation of the object I've just created
in the post/put method I have to call handleGet():
public void post(){
[...] // create the resource
getResponse().setStatus(Status.SUCCESS_CREATED);
getResponse().setRedirectRef(...);
// return a representation of the newly created resource:
handleGet();
}
Isn't that a bit confusing?
And what if I want to return the representation of another resource?
For instance, a CAPTCHA the user must answer to confirm the creation of
the resource. It that case, I'd need to to know what is the client's
preferred variant.
>
> The confusion probably comes from the increased responsibility of Resource.
> In RC2, all the handle*() methods were implemented in the Handler.
It is still a bit confusing to me that a Representation inherits from Variant.
I'd tend to see the variant as an attribute of a representation (variant=type,
representation=content).
The fact that you have to do a downcast in Resource.getRepresentation indicates
to me that something isn't quite right:
public Representation getRepresentation(Variant variant) {
Representation result = null;
if (variant instanceof Representation) {
result = (Representation) variant;
}
return result;
}
In other words, I'm not sure this hierarchy respects the Liskov substitution
principle.
Thanks,
-Vincent.