views:

149

answers:

4

Hi guys,

I'm developing a REST api, and I'm wondering the following:

I want to use HTTP PUT to update some entities in the webservice. The format will be a urlencoded body. Is it acceptable to only update the fields that were actually specified, rather than the entire entity?

I'm asking, because PUT would be a very convenient method to do some updates, but I don't want them to remove fields if they just happened to misspell some of them. Additionally, I don't want to force the implementor to always have to do a GET first and copy every single field they might not actually use..

+1  A: 

I would say it may make sense. I consider the REST idea very flexible, so if you Update one entity why not only transfer the fields that need to be updated in your implementation. It is true, that it needs more server sided effort though. You have to check if the entity is available and can be updated with the data transferred and you need validation checks (as opposed to schema free document oriented data).

<!-- PUT books/1337 -->

<book>
    <title>Hello</title>
    <author>John Doe</author>
</book>

<!-- PUT books/1337 -->

<book>
    <title>Hello here I am</title>
</book>
Daff
The REST idea may be flexible, but it does say that the verbs you use should have uniform behaviour. HTTP is quite specific on how PUT should be handled. The consensus is that PUT should replace the entity and not do what you are suggesting.
Darrel Miller
Yepp I agree that POST is the best choice then. As flexible as it it put one shouldn't break the basic ideas/rules.
Daff
+2  A: 

Put is only for complete replacement. There is a proposal for the verb PATCH to address the problem you have (http://www.ietf.org/internet-drafts/draft-dusseault-http-patch-14.txt)

Patch, however, still may not be what you want. What is sent is an update resource that can do things like increment counters and so, unlike put, isn't idempotent.

You could expose each field as a resource and do multiple puts to each field. You can pipeline the puts to mitigate the extra latency.

Tony Lee
PATCH is, like you mentioned, still a draft.. Multiple PUTs would be highly annoying :) I could use POST for all this instead.. PUT would be much nicer though..
Evert
Agreed that POST is likely your best option - but do consider pipelined puts if the # of fields updated is small relative to the total number of fields.
Tony Lee
+2  A: 

You could simply POST the updated properties to the resource. Remember POST is the catch-all verb that you can use to do whatever you need to do when the other verbs don't work for you.

Check out Roy's article It's ok to use POST

Darrel Miller
+1  A: 

I've never liked any of the solutions for partial updates, either. If I were designing a web service for widespread use, I'd probably go with POST. If it were for use by a fairly small number of people, i.e., I could talk to all the people I expected to call it, I've had two different ideas for addressing it.

  1. PUT to a new 'update' resource. It would basically record the update you want to apply and then be in charge of not applying duplicates. I envision this working somewhat like a version control system that keeps a list of patches/changesets and gets pretty complicated every time I try to think out all the corner cases.

  2. PUT to the resource, but don't change any fields that are not present. Require fields that you want to NULL out to be present with a special attribute indicating that you want to NULL it out. This seems far more practical, but doesn't fit in very well with the consensus that PUT should be a complete update.

If anyone has pointers to discussions of similar ideas, please edit/comment accordingly.

Hank Gay
I have the same sentiments.. Even though it might not be exactly what PUT was intended for; I will do post-processing anyway on the request (it will go into the DB and it will have different representations/formats when people request it). I just feel this is how people expect it to work. I also want to keep POST for just creating child-elements (e.g.: inserts) so I feel in the end it's the most simple
Evert
@Hank - What's the reason to use PUT if you're going to violate its semantics? If I PUT something, GET should return it. Why not use POST regardless of who's consuming it?
Tony Lee
@Tony For one thing, the PUT would still be idempotent and the POST still wouldn't. Also, my natural thought process is *not* to erase things that aren't present; to me that's a DON'T-CARE, not a DELETE; DELETE/NULL should be explicit, not implicit. If the communication overhead is small, i.e., few people involved, I'd rather we agreed to what fits my natural thought-process than work around what I consider a design flaw. The communication overhead is why I wouldn't do that for a wide audience; at that point, the extra overhead would outweigh the benefits of reducing my mental friction.
Hank Gay