Adam Taft <adam <at> adamtaft.com> writes:
> a)  GET should NEVER! change the state of an object.  I'm confused as to 
> how/why you are mixing a DELETE operation and a GET operation together. 
>   I'm probably mis-reading.

Yes, I must not have been clear.  My GETs aren't changing the state of an
object, nor are the GET and DELETE mixed together.  I was just using an example
of a situation where I have a resource that supports both GET and DELETE.

So in that situation, I can:

1 - Create a representation in the Constructor
When the resource is constructed, I can retrieve the resource from the
datastore, and if it exists, create a representation and drop it in the 
variants.

If it's a DELETE, I ignore the representation and delete in the datastore.  The
representation, and the time to create it, are wasted.  Two round-trips to the
database here where only one was necessary.

If it's a GET, I do nothing; the representation is already there or it isn't,
and RESTlet can decide to 404 or 200-with-representation, I don't have to do any
work.

2 - Check for Existence in Constructor
When the resource object is constructed, I can check to see if the resource
exists in the datastore.  If it does, I can drop a variant in the variants,
otherwise I do nothing.  

If it's a DELETE, I can use the information I gathered in the constructor to
delete the representation.  Once again, this is two round-trips to the database
where only one was necessary (if the resource exists).

If it's a GET, I can use the information I gathered to create a representation.
 This might be another database call, so this could again be wasteful.

3 - Check Method in Constructor
If it's a DELETE, there's no real reason to look in the database in the
constructor; I'd prefer the DELETE to be idempotent, so I don't want to 404
anyway.  So, I could decide to only check for a representation and populate the
variants if the method is GET. 

This is functional, and not very wasteful, but feels like I'm working at
cross-purposes with the API.  It's already got branching on methods, but I'm
going to put a method-conditional in the constructor?

4 - Do The Work Later
Do very little in the constructor; toss in a variant in the hopes the resource
exists.

If it's a GET, I work in getRepresentation(Variant) to check if the resource
exists.  If it does, I return a null variant and set the status code.

If it's a DELETE, I issue a SQL delete that may or may not remove a record and
do nothing else.

This approach does the least work, so is probably the best from a performance
perspective, but it again feels like I'm working a little cross-purposes in 
the API by bypassing all that "If there's no variant, then 404" code in 
Resource.

Actually, I'd be happy with this if Resource.handleGet() treated a null from
getRepresentation as a 404, but that might not work for all cases?

--

So is that more clear?

> GET should only retrieve a representation.  Usually, most GET requests 
> have some sort of candidate-key associated to them (in the URL string) 
> that can uniquely identify the resource.  All you should have to do is 
> start querying your database.  If at the point in time you perform the 
> query, the record is not in the database, the query result will tell you 
> this (the size of the result set, or other means).
> 
> So, just simply retrieve the object.  If it's in the database, great. 
> Return 200.  If not, return 404:

Sure -- you're proposing to do this all in getRepresentation(), as in my #4 
above?

> b)  DELETE should NEVER! return a 404.  Your server should be happy to 
> accept DELETE requests to any (logical) resource, whether or not that 
> resource actually exists or not.

Sorry, I didn't mean to imply that I wanted to 404 the DELETE.

> This comes back to the basic definition of REST:  Representational State 
> Transfer.  When you delete a resource, you're really asking that the 
> state of the resource be moved into the 'deleted' state.  If a resource 
> is already in the deleted state, that doesn't matter.

Well, a resource that never existed isn't in the "deleted" state per se, but 
I know what you mean, and agree.

> Just let your transactions come in which ever order they come in.  If a 
> GET comes before a DELETE, or vice versa, that's ok.  I think you're 
> trying to tie the two together or something?

Nope; hopefully the above clarifies my intent somewhat.

 - Geoffrey

Reply via email to