WebDAV vs HTTP method semantics

Roy T. Fielding fielding@ebuilt.com
Tue, 25 Sep 2001 21:11:59 -0700

I got a bit behind in my mail while in New Zealand...

On Mon, Sep 03, 2001 at 01:19:25AM -0400, Mark Baker wrote:
> > On Sat, Aug 25, 2001 at 11:26:57AM -0400, Mark Baker wrote:
> > > 
> > > My hypothesis is that, at least in theory, all operations with side
> > > effects on resources can be represented with only PUT or POST.  Here's
> > > an attempt to recast LOCK, COPY, and MOVE in that way.
> > 
> > Yes, they can, but it isn't a good idea to do so.
> >
> > The REST style doesn't suggest that limiting the set of methods is a
> > desirable goal.  What it does suggest is that designing an architecture
> > for which the common case is optimized will produce greater results if
> > the common case is very general indeed, and thereby applications that
> > conform to the general case will benefit from the optimizations and
> > deployment via the network-effect.
> I couldn't agree more with that second sentence, but I guess I've been
> taking is as given that "very general" = "limited set of methods".
> You don't agree?  Or do you simply mean that it's not a goal, just a
> side effect of keeping your eye on the "very general" ball?

It is more a side-effect of Simplicity as a goal, but yes -- very general
means that the common case is just a few methods.  However, we still need
a way to distinguish between the common case and the uncommon cases.  The
point is that making that distinction in the method name, and hence not
limiting methods, allows the uncommon case to fall into a less-critical
processing path than the common case.

> > That is where the similarity between Linda's tuple-space and REST ends.
> > REST does not restrict the system to a limited set of methods -- what it
> > does is restrict the interface such that the methods are easily identifible,
> > and then only attempts to optimize those that are known to be the common
> > case -- GET, and to a lesser extent the data-provider form of POST.
> > Applications that need the benefits of the common case will gravitate
> > toward the generic methods on their own accord.
> >
> > In particular, REST encourages the creation of new methods for obscure
> > operations, specifically because we don't want to burden common methods
> > with all of the logic of trying to figure out whether or not a particular
> > operation fits the 99.9% case or one of the others that make up 0.1%.
> Perhaps this 0.1% case falls outside my "in theory" qualifier.  It's
> not clear to me.

I'm not sure how to describe it.  What we are doing is separating concerns
so that the 99.9% of operations never have to worry about (run code for)
the 0.1% of operations.  That is a basic network performance trick, commonly
seen in the ASIC designs of TCP/IP routers.

> M-POST for example.  Useful semantics, theoretically doable over POST.
> But not practically.
> > Doing everything with a common method means that intermediaries must
> > look to other parts of the message to differentiate semantics, which
> > causes intermediaries to go through an excrucuating amount of effort
> > in the common case just to find out what operation to perform if a
> > message happens to be the uncommon case.
> Obviously I wasn't clear.  On to an example ..
> > > LOCK's side effect is to change the state of the resource identified by
> > > the Request-URI to one of locked (per WebDAV lock semantics).  It does
> > > this relative to the current state of the resource, not to the exclusion
> > > of it (duh), so this should use POST not PUT.  But how do we use POST?
> > > We POST a lock entity, describing the type of lock.
> > > 
> > > e.g.
> > > 
> > > <?xml version="1.0">
> > > <lock xmlns="http://www.ietf.org/rfc/rfc2518.txt" />
> > > 
> > > The use of an XML namespace being the extensibility mechanism I mentioned
> > > above.  Content-Type on the POST wouldn't have been appropriate because it
> > > is an attribute of the representation, not the resource itself.  The
> > > namespace describes the resource.
> > 
> > Nope, in that case you might as well just use XML-RPC.  There is another
> > way to tackle the same problem that is closer to REST's type of genericity.
> "lock" is a noun, not a verb, so I don't see this being similar to RPC at
> all.

A lock is a resource state.  The LOCK verb isn't just creating a lock, it is
asking the server to check for an existing lock and modify the state of the
resource if one doesn't already exist.

> This is quite different than a new HTTP method for at least one big reason;
> a successful invocation of the LOCK method means the resource is locked,
> whereas a successful POST of a lock noun entity means the resource was
> accepted and processed - it doesn't mean that it's locked.
> But for those resources that *do* know what a lock is, their processing
> of it *may* end up with a lock in place.  I'm trying to figure out how
> far we can reasonably go with this "may", and if it can be formalized at
> all to make it useful in place of a new HTTP method in some cases.

The question you need to ask is: if the resource responds with 200 OK, does
that mean we have successfully locked the resource for exclusive access?
I don't see how you could know that for certain via a POST when there is
no way to know what POST will mean to the resource.

Note that it is possible to implement anything via POST (that's why it exists).
What isn't possible is for the client to know what it accomplished by way
of the POST.

> > Instead, consider a lock to be another resource with a special relationship
> > between itself and the resource that you wish to deny others access.
> > What is the state of that lock resource?  How may different values of
> > that state influence temporary access control to the other resource(s)?
> > There already exists a large amount of research that defines how management
> > of one variable can determine the coordination of access for some other
> > variable(s).  And it is very simple to translate that into HTTP, once you
> > separate actions on the lock resource from actions on the resource to be
> > locked.
> Absolutely.  So POST the lock noun, create a new resource for the lock,
> and return a 201 with a Location header pointing to it.

But POST doesn't mean anything.  You need to establish a relationship that
means it is a lock for that other resource, which is difficult to do in a
way that is both atomic and visible to intermediaries.

What I would have done (and this was proposed at an early DAV meeting) is
define a single resource metadata field for HTTP responses that gave a URI
prefix for operations on properties of that resource.  E.g.,

   Properties: "http://example.com/this_resource;props"

and then simply define that namespace in the same way as old server-side
image maps were defined.  You could then do

   GET http://example.com/this_resource;props?lock HTTP/1.1

to find out if the resource has a lock, or

   PUT http://example.com/this_resource;props?lock HTTP/1.1

to demand one for yourself.  Note that the entire URI prefix is determined
by the origin server, so the properties might even be on a different server
than the resource.  And if you just want a list of all properties, then

   GET http://example.com/this_resource;props HTTP/1.1

will do just fine.  Of course, that assumes a standardized namespace for
property names, such that "lock" has meaning to both client and server,
to which some people seem to be allergic.

That one level of indirection allows all properties to be resources and
solves the nasty cruft added by DAV for ACLs and versioning.