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

