Hi Vincent,

> 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.

Indeed, in the constructor you shouldn't do any processing specific to a
given method (GET, POST, PUT or DELETE). You should always declare the
variants you want to expose (maybe based on some authentication
verifications), initialize some member variables with important URI
attributes and also lookup the associated domain objects from your
persistent store.

Even for a PUT this is useful. Indeed, when the handlePut() is invoked after
construction, it will do some preprocessing then call your
"put(Representation entity)" method. In this method you will easily know if
your domain object was found at construction time and can guess if you need
to CREATE a new one or simply UPDATE the existing one.

> 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? 

You seem to get confused by the meaning of PUT which is not only used for
creation but also for updating resources. See HTTP spec:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6

> 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();
>      }

Hmm, let's got back to the POST definition:

"If a resource has been created on the origin server, the response SHOULD be
201 (Created) and contain an entity which describes the status of the
request and refers to the new resource, and a Location header (see section
14.30)."

Notice that your response entity should "describe" the status rather than
just return a representation of the created resource. The client should then
GET the created resource at the URI indicated by your Response.redirectRef
property.

So, it seems that the handleGet() is not necessary here. If you still want
to return a negotiated resource representation as a status description page,
you should then call handleGet() before setting the status to CREATED
otherwise it will be overridden.

> Isn't that a bit confusing?

Let me know if that didn't clarify it enough.

> 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 know what is the client's
> preferred variant.

This is a of a REST design question. In this case you seem be referring to a
multi-step creation process. I'm not sure how exactly I would handle this
case, but you can always get the preferred variant of a resource by calling
the Resource.getPreferredVariant() method or eventually the
ClientInfo.getPreferredVariant(variants, defaultLanguage).
 
> 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.

This is debatable. I view it this way: a VARIANT "is an" OBJECT that
contains some metadata property (type, languages, etc.) and a REPRESENTATION
"is a" VARIANT that provides some actual content. 

At some point in the past I had a RepresentationMetadata class similar to
Variant and a Representation.metadata property but it was a bit cumbersome
to have to do request.getEntity().getMetadata().getMediaType() to just get
the media type of a request entity. Now you can just do
request.getEntity().getMediaType() with looks better IMO.

Best regards,
Jerome  

Reply via email to