mark nottingham

Using WebDAV as a Description Format for REST

Tuesday, 27 April 2004

HTTP APIs

In the past, I’ve talked about reusing WSDL as a format for describing Web resources, as well as coming up with a bespoke format.

One path that I’ve overlooked so far is reusing WebDAV to describe Web resources. The WebDAV protocol defines and allows you to describe the properties of a Web resource; e.g., the last-modified time is such a property, and so is the fact that it requires authentication.

WebDAV also defines a way to get a representation of the properties of one or more resources, with the PROPFIND method. If you send a PROPFIND to a resource along with a Depth HTTP header, you can get back a “multistatus” response, which describes the properties of a number of related resources, in an extensible XML format.

With only a small amount of imagination, WebDAV’s multistatus format could be viewed as a Web resource description format. However, there are some limitations which, in my mind, make it unsuitable. Let’s dig a bit deeper.

If we go back to our address book example, it might look something like this through WebDAV goggles;

<D:multistatus xmlns:D="DAV:">
     <D:response>
          <D:href>http://www.example.com/people/Bob</D:href>
          <D:propstat>
               <D:prop>
                    <D:creationdate>2004-04-08T17:42:21-08:00</D:creationdate>
                    <D:displayname>An entry in the address book.</D:displayname>
                    <D:getcontenttype>text/html</D:getcontenttype>
               </D:prop>
               <D:status>HTTP/1.1 200 OK</D:status>
          </D:propstat>
     </D:response>
     <D:response>
          <D:href>http://www.example.com/personFinder</D:href>
          <D:propstat>
              <D:prop>
                    <D:creationdate>2004-01-12T13:22:09-08:00</D:creationdate>
                    <D:displayname>Finds entries in the address book.</D:displayname>
                    <D:getcontenttype>text/html</D:getcontenttype>
                    <x:queryArgs xmlns:x="..." xmlns:xsd="...">
                        <x:arg name="name" type="xsd:string"/>
                    </x:queryArgs>
               </D:prop>
               <D:status>HTTP/1.1 200 OK</D:status>
          </D:propstat>
     </D:response>
</D:multistatus>

Using an existing format would be a great boon, but I see a few potential problems here.

First of all, there’s no means of typing resources; i.e., you can’t say that all Foo resources require authentication, allow GET and POST, and produce HTML; you have to enumerate each of them, and repeat the appropriate metadata for each one. I suppose one could describe a synthetic resource (e.g., by making D:href point to a URI that identifies the type, rather than a specific instance of it). This seems a bit of a hack, though, considering the semantics of multistatus.

Another is content negotiation; as far as I can tell, WebDAV doesn’t support describing different representations of the same resource. Also, I can’t see any way to accommodate generative resource names in this format, without breaking a lot of existing WebDAV implementations. Altogether, these are pretty limiting problems; while you could probably come up with workarounds, it wouldn’t be a very easy format to edit or visualise, at least without the help of tools.

Another way of seeing these problems is in terms of abstraction; where WSDL went too far, this format doesn’t go far enough — not that this is WebDAV’s fault, as I’m trying to do something that it’s not really designed for. I don’t think we can just pick up this format and use it to document the interface provided by Web resources.

How About Reusing Properties?

Still, the property model is compelling; there are a large number of them defined (I’ve taken a first pass at a collection of properties defined in RFC and I-Ds, as alas, there is no registry yet), and they cover a pretty useful swath of functionality.

Additionally, if your description format is compatible with them, WebDAV becomes much easier, and that’s a good thing; it can readily be seen as an alternate UI for resources, one that makes a lot more sense than a browser in some use cases. In the other direction, WebDAV could be used as an update and synchronisation protocol for resource descriptions, if desired.

Unfortunately, another problem pops up; because WebDAV properties have the granularity of an entire resource, it becomes difficult to use them to describe things on a finer grain.

For example, this is a WebDAV property that describes the access control requirements of a resource;

<d:acl xmlns:d="DAV:">
    <d:ace>
        <d:principal>
            <d:href>http://www.example.com/acl/groups/maintainers</d:href>
        </d:principal>
        <d:grant>
            <d:privilege><d:write /></d:privilege>
        </d:grant>
    </d:ace>
    <d:ace>
        <d:principal><d:all /></d:principal>
        <d:grant>
            <d:privilege><d:read /></d:privilege>
        </d:grant>
    </d:ace>
</d:acl>

As you can see, it gives rights like “read” and “write”. In a description of a Web interface, the most natural level to talk about these things is at that of methods, not resources; e.g., “GET allows anyone, but PUT allows maintainers.” While there is a mapping from WebDAV privileges to the appropriate HTTP methods, it’s not a direct one, and it isn’t clear how you’d handle things like POST (in fact, the current draft of WebDAV ACL doesn’t talk about POST at all).

Conclusions to Date

Make no mistake, WebDAV is a great protocol, and I’m excited about the possibilities for its use. However, the multistatus structure really isn’t suitable for the description of Web interfaces; although it’s capable of doing so in limited cases, it doesn’t encourage good practices in their design.

Likewise, WebDAV properties are ripe for being leveraged, except that they suffer from a fixed scope — that of the resource. As Jeff Mogul’s paper [pdf] points out, there are a lot of different levels where it’s interesting to talk about HTTP metadata.

In many ways, this is no different than the trade-offs inherent in leveraging WSDL; while it would be functional, its questionable whether reuse brings enough benefits to justify fitting a round peg into a square hole (or vice versa). Neither WebDAV multistatus nor WSDL was designed to describe stateful resources that have multiple representations and a constrained number of methods bound to a single protocol, HTTP. Neither, when used in this way, promotes good resource modelling (an art for which there isn’t nearly enough guidance available).

Of course, any description format’s mechanisms (like acls, redirect and so forth) will need to define a mapping to WebDAV properties to ensure that WebDAV is enabled. The trick will be making that mapping fairly direct and easy.

The net is that, so far, I think we need a clean-room format that’s designed to promote good practice. Before I go much further down that path, however, I need to explore one or two more options for reusing existing formats.


6 Comments

Julian Reschke said:

“I suppose one could describe a synthetic resource (e.g., by making D:href point to a URI that identifies the type, rather than a specific instance of it). This seems a bit of a hack, though, considering the semantics of multistatus.”

No, that’s absolutely acceptable and is what (gasp) MS Exchange and MS Sharepoint actually do. The RFC3253 REPORT method even has support for following relations inside DAV:href elements in properties (see DAV:expand-property REPORT, http://greenbytes.de/tech/webdav/rfc3253.html#REPORT_expand-property).

“Another is content negotiation; as far as I can tell, WebDAV doesn’t support describing different representations of the same resource.”

That’s indeed an issue, and it has been on the to-do list of the WebDAV WG for quite a long time. However, other features (such as ACL) have had a higher priority.

I’m not sure about the “generative resource names” issue – couldn’t this live as property on the parent collection?

Property Registry: this has been on the WG’s agenda for some time, but at the end it wasn’t clear whether it’s actually needed. I’ve got the machinery ready to automatically extract property definitions from all RFCs and IDs (as long as they exist in RFC2629 format); I just didn’t have yet the time to tune and publish the results.

On POST ACLs: the ACL spec deliberately doesn’t try to define this, as POST can do basically anything. For instance, if you use POST for the Atom API (is this still in the spec), POST can either be PUT or DELETE, thus is controlled by completely distinct ACLs. This is why it’s good to have explicit method names (see current discussion on Lisa Dusseault’s PATCH method proposal).

Anyway, thanks for the interesting article!

Wednesday, April 28 2004 at 9:58 AM

Julian Reschke said:

In the meantime, I’ve put the “HTTP/WebDAV index” (containing all index entries extracted from the RFC2629-formatted versions of the specs) online:

<http://greenbytes.de/tech/webdav/common-index.html>

(Scroll down to entry “Properties” to get to the full list of currently defined properties).

Also, the ACL Protocol has been published a few days ago as RFC3744.

Best regards, Julian

Saturday, May 8 2004 at 4:40 AM

Julian Reschke said:

Hi Mark,

on index generation: I wasn’t aware of that. In the XML versions of RFC2616, RFC2518, … I’m using a very regular format for the index (iref) tags. So it would be a trivial XSLT transformation to produce RDF from that. Maybe you can point me to a sample RDF (or post an example)?

on ACL semantics: Probably because the WebDAV family of specs has a really rapidly growing number of HTTP methods, and defining privileges for particular methods would require every other spec to define it’s relation to ACL. Furthermore, the set of privileges needed for a specific method may depend on the request body and it would be impossible to come up with a generic definition. For instance, this applies to POST and REPORT; the Atom API for instance is using POST to marshall DELETE semantics in case a client doesn’t support submitting DELETE directly.

Best regards, Julian

Sunday, May 9 2004 at 12:23 PM

Julian Reschke said:

That’s a very good example. DELETE does two things:

1) it MUST modify the state of the collection from which the member is removed (assuming WebDAV resources),

2) it MAY remove the actual resource (for instance, the resource may have more URLs mapped to it, so applying DELETE to one of them wouldn’t affect the resource at all).

So you will need the privilege to remove a binding from the parent collection (DAV:unbind), and you may need the privilege to “destroy” the resource (as this operation isn’t defined anywhere in WebDAV, it’s not even mentioned in the WebDAV ACL spec; servers however may implement this as a custom privilege).

Best regards, Julian

Friday, May 14 2004 at 5:59 AM