Hi all,

This is an interesting thread and I don't have any strong opinion on it yet. Maybe it would be useful to relaunch this thread in the REST-Discuss list on Yahoo. You could get the opinion of the larger REST community and potentially of Roy T. Fielding too.

Best regards,
Jerome


Erik Hetzner a écrit :
Hi Adam,

At Wed, 18 Jul 2007 18:28:15 -0600,
Adam Taft <[EMAIL PROTECTED]> wrote:
I believe it is a principle of REST as applied to HTTP. Of course,
my last name is not Fielding, so what do I know.

Well, its called REST, not Fieldingism, so it’s open to
interpretation. :)

I'm not exactly following what you're saying about "AFTER each
request". Again, here's how I look at it, with two examples; your
PUT example and a caching example.

First, let's establish what a "request" is:  url + pre-condition
headers + HTTP method + message body (some methods requiring a message
body (like POST, PUT) and others not (like GET or DELETE)).

Here's the caching example:

Step 1)  A client requests a resource via GET.  It has not previously
requested this resource, so it has no ability to include a
If-Modified-Since or If-None-Match precondition header.

--- Client -------------------
GET /some/url HTTP/1.1
Host: foo

--- Server -------------------
HTTP/1.1 200 OK
Etag: "abcdefg"

message body


A 200 OK is returned, along with a new Last-Modified and/or Etag
header. For simplicity, we'll just use the ETag, which the client
records along with the cached version of the resource.

Step 2)  A client makes a request for the _same_ resource using the
_same_ url.  However, this time the client uses a If-None-Match
precondition in the request.  Thus, the "request" itself (as defined
above) is different.

--- Client -------------------
GET /some/url HTTP/1.1
Host: foo
If-None-Match: "abcdefg"


--- Server -------------------
HTTP/1.1 304 Not Modified


The server replies with a 304 Not Modified reply.  The server can
return a different status code because the request is different.  It
will always return this 304 Not Modified reply until the resource
changes (for that specific request).  It will always return a 200 if
the precondition header is not included.  The server is unable to
escape these rules.

The point is, notice that the Request has changed.  It doesn't matter
how many times you throw the first request at the server, it will
always return 200.  Likewise, the second request will always return
304, until the resource's state changes.

This exact same evaluation can be applied to your PUT example, except
of course the server replies with Precondition Failed (which according
to the spec is an appropriate response for a PUT method under the
circumstance you describe).  It will always return 412 after the first
PUT for identical requests (because the first request modifies the
resource, and thus allows the server to return a different status code
for the same request).

That's the core of my argument:  A status code should always be the
same for an identical request so long as the resource has not change.

If the server is coded to return a different status code for an
identical request when the resource state has not changed, then that
is wrong.  The only liberty a server has to return a different status
code for the same request is when the resource has changed.

Ok, but you argued against a DELETE returning 404 with the argument
that the response to a request should depend only on the state of the
resource AFTER the request has been processed (ie, a non-existing
resource). Otherwise, there is not a problem with returning a 204 or a
404 because the resource CHANGES; in the first case it is deleted, in
the second case there is no change.

Put another way (I hope this makes sense), your argument was for:

<request method, server state before> =>
  <response status, server state after>

<DELETE, existing resource> => <204, non-existing resource>
<DELETE, non-existing resource> => <204, non-existing resource>

and against:

<DELETE, existing resource> => <204, non-existing resource>
<DELETE, non-existing resource> => <404, non-existing resource>

Because you insisted that the server should only care what the server
state is AFTER the request (that is, a non-existing resource) and
should not care what the state was like BEFORE the request (existing
vs. non-existing). Now you are saying that we SHOULD take into account
what the state is like before the request; that is, ETag: "A" or ETag:
"B", even though the state AFTER the request is processed (ETag: "B")
is the SAME.

You're right.  PUT should never return 201 Created.  The reason?  201
Created should have a Location: header sent in reply.  The client
doesn't need a Location: header, since it already knows the location
the resource.

The client doesn't care whether the resource was _newly_ created, or
just _updated_.  What does the client care?  This goes back to the
same argument about DELETE.  So long as the state change for the
resource occurred, that's all the client cares about, not whether it's
newly created or not.  What is newly created anyway?  And, what does
the client care to know the difference?

The 201 Created status code is only useful when the resource's URL is
not known by the client.  Therefore, 201 Created is only applicable to
the POST method, because POST doesn't know what the url is for the
resource in its message body.

A successful PUT can return 204 No Content for an immediately
successful state change, or 202 Accepted for one that will occur in
the future. There are no other 2xx response codes appropriate for a
PUT operation.

Sorry, all these paragraphs are just wrong. From 9.6 (PUT) of RFC
2616:

| If a new resource is created, the origin server MUST inform the user
| agent via the 201 (Created) response.

Again, this is not arguing HTTP spec, as the HTTP spec is quite a bit
more lenient than the rules I've suggested.  And, the rules I've
suggested may not strictly be REST rules, as I believe Fielding was
describing REST as an architectural pattern that is applicable to
protocols other than just HTTP.

It is arguing the spec, because (a) you are advocating something that
violates the spec, and (b) you were previously laying down as settled
law (do not return a 404 from a DELETE) that is not in the spec & and
is not clearly defined in Fielding’s thesis and may or may not follow
from these principles.

True, REST is applicable to other protocols.

However, if you follow the HTTP spec and you apply the REST principles
to it, I believe what you end up with is this logical mapping of what
HTTP status codes can be returned for which HTTP methods.  For 2xx
only, it goes:

GET => 200, 206
PUT => 204, 202
POST => 201, 202, 205
DELETE => 204

Look, you can’t argue against a MUST in an RFC. Either you come up
with HTTP-next generation, or you follow the spec.

HTML is an abomination to the HTTP spec.  So, I'm not arguing what is
in current use, more what it ideally should be.

Huh?

No more replies from me.  I feel I've hijacked the thread, and we're
obviously way off RESTlet discussion.  ;)

True, I didn’t mean to start all that.

best,
Erik Hetzner
;; Erik Hetzner, California Digital Library
;; gnupg key id: 1024D/01DB07E3

Reply via email to