开发者

Partially updating complex types in a RESTful Service

I am using JSON with RESTful service. Implementation is like this.

GET on http://hostname/a returns

{
    "a": {
        "b": {
            "c1": "data1",
            "c2": "data2" 
        } 
    }
}

GET on http://hostname/a/b returns

{
    "b": {
        "c1": "data1",
        "c2": "data2" 
    } 
}

I wanted to know the correct behavior of POST(and PUT) on http://hostname/a

{
    "a": {
    开发者_如何学JAVA    "b": {
            "c1": "newdata" 
        } 
    }
}

Should it just update the c1 with value "newdata" or it should replace the whole resource b, thereby just containing c1 ( i.e. c2 is overwritten and doesn't exist anymore)


You have hit upon one of the most debated issues that I have seen in my time dealing with REST over the last few years.

Here's the simplistic answer:
The general consensus is that the HTTP PUT method has replace semantics and therefore c2 is overwritten and does not exist anymore.
The PATCH method was recently introduced to help people deal with partial updates.

Now, here are two complications to the scenario:

  1. Why must PUT have replace semantics? What are the negative effects of doing partial updates? I've yet to hear a really convincing argument.

Actually, the HTTP spec does not specifically say PUT has replace semantics, it says:

The PUT method requests that the enclosed representation be stored at the effective request URI

however, it also says

HTTP/1.1 does not define how a PUT method affects the state of an origin server.

  1. It is accepted that if you assume PUT has replace semantics that a server may include some content in a representation that is not replaced. e.g. If a representation contains links, doing a PUT of a representation that does not contain those links does not "delete" those links. Same for a timestamp field, or last modified data. The eternal question is how do we define which content is removed when omitted by the client and which stays because the server says so!

Personally, I avoided PUT because I found the "replace" semantics too constraining. However, recently I am starting to be convinced by Mike Kelly and Mike Amundsen that maybe PUT should be considered more flexible than we currently give it credit for.


First of all, if you change a 'b' resource, why not you send POST(or PUT) to http://hostname/a/b instead of just http://hostname/a ? If something worth to be pointed/linked, it should be implemented as resource, according to RIA philosophy, and has got it's own URI.


If you PUT to http://hostname/a what happens to cached copies of http://hostname/a/b? How long are they allowed to be out of sync?

If the answer is "they're not cached"...?

"The primary disadvantage of layered systems is that they add overhead and latency to the processing of data, reducing user-perceived performance. For a network-based system that supports cache constraints, this can be offset by the benefits of shared caching at intermediaries." -- A famous dissertation.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜