mnot’s blog

Design depends largely on constraints.” — Charles Eames

Sunday, 17 February 2008

Protocol Design Standards Web Web Services


It’s 7am, I’m sitting in the Auckland Koru Club on my way home and reading the minor kerfuffle regarding PATCH with interest.

For me, the critical difference between PATCH and POST is generality; PATCH is a generic method (as all good HTTP methods should be), while POST is not (the exception that proves the rule). As such, it should be possible to take a PATCH request and a current representation of the resource it’s being applied to and — only armed with knowledge of the format that the PATCH request has chosen to use — accurately determine what its new state is.

James says

[..] using POST is still problematic, mainly because it ties the client to whatever meaning any particular server implementation wishes to assign to POST in any given context. E.g. POSTing one of Rob’s “x-application/json-sync” resources to the Edit URI of an Atompub entry has a different meaning that POSTing the same resource to the URI of an Atompub collection URI. Using PATCH would avoid the ambiguity entirely and ensure that the same request would have the same meaning regardless of the URI.

which I totally agree with — provided that the request really is unambiguous, and doesn’t have a lot of resource-specific semantics that aren’t captured in those of PATCH.

For example, the common case that I see is what Joe originally spelled out; a special resource is minted that has the semantics of updating other resources (e.g., for batching). While you can fit this sort of thing into a world view where you’re PATCHing a special-purpose resource that has side effects on other resources, I think it’s a looong stretch to say that this is just a PATCH; POST would make it more clear that something special is going on here and require that the protocol be really spelled out somewhere.

In short, while PUT and PATCH can have side effects, if the whole point of the resource is to propagate those side effects, you might be stretching the semantics of these methods too far, and providing a false sense of security (what’s called “standards air cover” by the cynical), by extending their semantics in non-standard ways and relying on clients understanding what you’re doing under the covers.

Likewise for PATCHes that contain obscure or special-purpose patch document formats. If you’re creating application/x-my-apps-patch-format, you’re not doing anybody any favours by using PATCH, which needs to be paired with a standard patch format to be of any real use.

This is why I found Rob’s post so interesting; a lot of my concern in using PATCH has been that creating patch documents is a difficult thing to do on the client side (e.g., with JavaScript). The existence of sync.js makes this a lot easier — provided that your data model is JSON. Anybody got one for XML?


Erik Mogensen said:

Providing a javascript library to provide diffs simply underlines the fact that the PATCH method moves a lot of complexity from the server to the client. Bad idea.

HTTP is so simple. GET this, modify it, PUT it back. Great. PATCH is not so simple. GET this, modify it, invoke complex routine which I don’t understand, PATCH the server.

Pair that with the fact that you need to tell the server which representation you’re actually patching, since Content-Type: x-application/json-sync or whatever.

Then there’s the issue of the proliferation of diff formats, probably more than one for each content type. And what if I want to blur a 50x300px area of a jpeg? Should I be able to PATCH that too?

Didn’t a couple of wise men say that if you want of a new method, what you really want a new resource?

Sunday, February 17 2008 at 6:34 AM