4

想象以下场景。我为我的库服务创建并发布了库 API 的第一个版本 (v1.0)。它希望所有新书都以以下三个值发布:

POST /books HTTP/1.1
Content-Type: application/json
...
{
  "title":"The Life of Beethoven",
  "author":"David Wyn Jones",
  "publisher":"Cambridge University Press"
}

--------
HTTP/1.1 201 Created
Location: http://example.com/books/12345

一些用户开始使用这个 API。几个月后,我发现我需要为用户提供发布该版本的选项(如果他们有该信息)。因此,我向我的 API (v1.1) 发布了一个次要的、向后兼容的扩展,以便现在接受 edition 属性,但仍然是可选的。现在,我的一位用户 Joe 可以成功发布以下内容:

PUT /books/12345 HTTP/1.1
Content-Type: application/json
...
{
  "title":"The Life of Beethoven",
  "author":"David Wyn Jones",
  "publisher":"Cambridge University Press",
  "edition":"First"
}

然后有这个:

GET /books/12345
Accept: application/json

返回:

HTTP/1.1 200 OK
Content-Type: application/json
{
  "title":"The Life of Beethoven",
  "author":"David Wyn Jones",
  "publisher":"Cambridge University Press",
  "edition":"First"
}

然而,假设 Nancy 没有将她对 API 的使用升级到 v1.1;她还在1.0。因此,她永远不会发布带有版本信息的书。她会发出 GET(如上)并获得信息,但会被忽略(因为她可以忽略她不理解的属性)。

但是,如果 Nancy 需要检索此资源然后通过她的 1.0 API更新它,这一切都会崩溃。她的请求如下所示:

PUT /books/12345 HTTP/1.1
Content-Type: application/json

{
  "title":"The Life of Beethoven",
  "author":"David Wyn Jones",
  "publisher":"Cambridge University Press"
}

这个 PUT 应该完全替换这个资源的表示,对吧?这是否意味着服务器需要完全消除 edition 属性,使 Joe 的 edition 属性为空?服务器应该足够聪明,只更新属性或它提供的资源,还是客户端有责任传回它不理解的属性?前者意味着服务器的工作量更大,但后者意味着只有一个编码不佳的客户端可能会为其他客户端搞砸服务器资源。

还有其他方法可以解决这个问题吗?你最近有没有解决这个问题,你是怎么解决的?

4

1 回答 1

2

如果您正在尝试向后兼容的服务器,那么我会让服务器仅在传递明确为空的字段值时删除值,例如

{
  "title":"Fahrenheit 451",
  "author":"Ray Bradbury",
  "publisher":"Penguin",
  "edition": null
}

这样,针对 v1.1 API 编码的客户端能够显式删除该字段值,但针对 v1.0 的客户端不会意外进行更改。

于 2013-10-04T17:56:50.463 回答