views:

206

answers:

4

As far as I see, there's no RESTful way to apply a modification to a resource. In order to do it, you have to PUT the resource as a whole, overwriting the previous representation. I think this is source of problems, in particular when the resource has a large representation.

I believe this hints at the lack of a verb in HTTP1.1 : something like MODIFY, or PATCH. Not even WebDAV has this verb (it has PROPPATCH, whose concept is similar, but not for the resources).

Isn't the current HTTP 1.1 set of verbs too limited for real world RESTing ?

Edit: I found a proposal at IETF about the PATCH verb

http://tools.ietf.org/html/draft-dusseault-http-patch-15

This specification defines the new HTTP/1.1 [RFC2616] method PATCH that is used to apply partial modifications to a resource.

A new method is necessary to improve interoperability and prevent errors. The PUT method is already defined to overwrite a resource with a complete new body, and can not be reused to do partial changes. Otherwise, proxies and caches and even clients and servers may get confused as to the result of the operation. PATCH was mentioned in earlier HTTP specifications, but not completely defined.

As far as I see, the only problem of such a verb is lack of idempotency.

Edit: As of March 2010, RFC 5789 exists (PATCH Method for HTTP).

+2  A: 

You could partition the resource into individually updatable sub-resources.

E.g. you have a /user resource representing user account information you could create a /user/email sub-resource, then do a PUT on it to update just the email.

DSO
+1  A: 

I wish there were standardized and supported verbs like...

  • FIND, SEARCH, or QUERY - so its clear the request is not for a resource, but the locations of other resources. Maybe only limited usefulness.
  • MOVE, COPY, LINK - just damn handy, they'd act similar to the command line tools.
  • DISCOVER, MAP, INDEX, or SITEMAP - so you can get a layout of resources, similar in concept to a wsdl file, or xmlrpc's system.listMethods.
  • BEGIN, ACQUIRE, or LOCK, and COMMIT, END, DONE, or RELEASE - to make it clear when you're starting and ending transactions, or using intermediate resources.
  • MODIFY, UPDATE, PATCH - because we all want it
Richard Levasseur
The REST man (Fielding) is not particularly fond of transactions. And as usual he does not explain what is, in his opinion, a RESTful approach. However, the issue is far from trivial, and locking is not the solution.
Stefano Borini
on FIND/SEARCH/QUERY, well... the idea of the web is that you perform verbs on nouns, and these nouns address resources. FIND is not a verb you can apply **to** a resource. it is a verb you apply to a service to find a resource. So it does not fit into REST very well.
Stefano Borini
Transactions are a part of life. If you have a multi part web request, auto-save functionality, or asynchronous communication, the server has to keep track of whats going on, and the client has to tell it when its done or beginning. Not everything can be pushed off to the client for sending all at once
Richard Levasseur
You can implement transactions RESTfully by making the transaction itself a resource. Either POST or PUT to create a new transaction resource, GET to get the current transaction state, and POST to update, commit or rollback the transaction.
DSO
You can add any methods you want. But then you are becoming less RESTful and more RPC over HTTP, which is fine, as long as you understand the implications of using REST versus RPC style.
DSO
if the transaction is a resource, then it's not restful. for two reasons: 1) it does not leave the state on the client, meaning that the server has scaling problems as the number of client increases 2) if the transaction involves also a third party server, then you have a distributed transaction to handle, and you delegate this to the server.
Stefano Borini
Transactions *are* part of life. They are also a part of many applications. But they should not be exposed by a RESTful interface. They should be hidden behind the REST interface.
Darrel Miller
Hmmm, FIND, SEARCH, QUERY... I prefer DISCOVER or maybe LOOKUP, or how about HUNT? Should it return an error if it does not find a result? Can I only return locations, or can I return some summary data too? ... Yes, I am being facetious. As soon as you try and introduce a new verb, you introduce a whole slew of questions that require getting consensus from a lot of people. Stick with GET and let the media type tell you whether what you received was a list or an individual item.
Darrel Miller
@Stefano: not all state can live on the client all the time. Clients crash, and not everything can be expected to be done in a single request.@DSO: The limited verbs force you into passing action flags in the body of the responses anyways, which just as RPCish as an extra verb.
Richard Levasseur
@Darrel: Just because it raises questions doesn't meant it shouldn't be done. Also, its a wishlist, not an ISO/W3C/OMG/IEEE spec. By your logic, browser vendors shouldn't try to support PUT or DELETE in <form>. An "auto save draft" feature is a transaction, and that has to be exposed somehow. BEGIN /msgs/001 is clearer than POST /msgs/001?action=draft or POST /msgs/drafts/001.
Richard Levasseur
@Richard PUT and DELETE have already been standardized in RFC2616. Why don't we try and get PATCH standardized first. It has been years in the making and there is a REAL need for that verb. However, as yet there is no consensus on how it should work. Let's not waste time trying to standardardize a "SEARCH" verb when GET works perfectly well. A list of links to resources is also a resource itself so it is perfectly consistent.
Darrel Miller
@Richard Based on your comment I think we are talking about two different kinds of transactions. I'm talking about transactions that hold locks in databases. Please tell me you are not suggesting that we should hold database locks whilst a user types a message? What I think you are talking about is what Fowler calls "Long Transactions" which require compensating actions instead of rollbacks. REST can handle "Long Transactions" perfectly well by creating a resource that represents the "Long Transaction"
Darrel Miller
Correct, I'm not talking about the SQL-specific concept of transactions. I'm talking about a process that has multiple steps and can't be completed in a single request. A client should have a way of saying "I need to edit this, I want a private copy I can edit as I go along", whether its backed by compensating txns, buffering, or (cringe) table locks is up to the app. I wouldn't say it handles it perfectly well; the limited verbs force you to overload one with special action flags to be passed with the normal request.
Richard Levasseur
Transactions may have a place in databases - but they have no place in REST. If you have a multi-part request then there are many options, the simplest being to make a new service which takes a single request and then attempts to make the 1,2,3 requests you need. If any fails then it returns an error. REST does not say you can't HAVE state - it just says that a request can't be dependaent on some saved state.
Gandalf
Actually, there are SEARCH, COPY, MOVE and PATCH.
Julian Reschke
yes, but none are standard
Richard Levasseur
Richard: exactly how are they not "standard"?
Julian Reschke
Point me to where they are standardized, _and_ a wide implementation of them?
Richard Levasseur
+2  A: 

You can use POST for partial updates. It's not ideal, but it's fairly RESTful.

Avi Flax
+1  A: 

There is good reason there is no such verb to do this. It's almost impossible to manage. Think of 100's of clients modifying the same resource in this way, how do you know where your modification ends up? What if order matters, and your "patch" is actually added after another "patch" and now what you meant to add i actually not what was added. Using PUT with ETag headers is a much more sane approach to modifying a resource then trying to hobble together some new verb with unknown results. Having to actually GET the resource is a small price to pay for repeatable results.

Gandalf
Well, you can do PATCH only if the ETag is the same as before. Optimistic locking. In that way it will be guaranteed that your modifications apply to the copy you referred to. I agree that there are other problems with this solution. I accept your answer because indeed you have a good point.
Stefano Borini