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

