我正在将 JSON 与 RESTful 服务结合使用。实现是这样的。
获取 http://hostname/a返回
{
"a": {
"b": {
"c1": "data1",
"c2": "data2"
}
}
}
获取 http://hostname/a/b返回
{
"b": {
"c1": "data1",
"c2": "data2"
}
}
我想知道 http://hostname/a 上 POST(和 PUT)的正确行为
{
"a": {
"b": {
"c1": "newdata"
}
}
}
应该只用值“newdata”更新 c1 还是应该替换整个资源 b,从而仅包含 c1(即 c2 被覆盖并且不再存在)
最佳答案
您发现了我在过去几年处理 REST 过程中遇到的最受争议的问题之一。
这是简单的答案:
普遍的共识是 HTTP PUT 方法具有替换语义,因此 c2 被覆盖并且不再存在。
最近引入了 PATCH 方法来帮助人们处理部分更新。
现在,该场景存在两个复杂情况:
- 为什么 PUT 必须具有替换语义?进行部分更新有哪些负面影响?我还没有听到真正令人信服的论据。
实际上,HTTP 规范并没有具体说明 PUT 具有替换语义,它 says :
The PUT method requests that the enclosed representation be stored at the effective request URI
但是,它也说
HTTP/1.1 does not define how a PUT method affects the state of an origin server.
- 如果您假设 PUT 具有替换语义,则服务器可能会在未替换的表示中包含某些内容,这是可以接受的。例如如果表示包含链接,则对不包含这些链接的表示执行 PUT 不会“删除”这些链接。对于时间戳字段或上次修改的数据也是如此。永恒的问题是我们如何定义哪些内容在客户端省略时被删除,哪些内容因为服务器这么说而保留!
就我个人而言,我避免使用 PUT,因为我发现“替换”语义太有限制。然而,最近我开始相信Mike Kelly和 Mike Amundsen也许 PUT 应该被认为比我们目前认为的更灵活。
关于web-services - 在 RESTful 服务中部分更新复杂类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4664566/