2

我正在创建现有 RESTful Web api 的 v2。

响应是 JSON 对象列表,大致形式如下:

[
  {
     name1=value1,
     name2=value2,
  },
  {
     name1=value3,
     name2=value4,
  }
]

我们在 v1 中观察到的一个问题是,一些客户端将按整数位置访问字段,而不是按名称。这意味着,如果我们决定在响应中添加字段(我们最初认为这是一种保持兼容性的更改),那么我们客户端的一些代码就会中断,除非我们在最后添加字段。即便如此,其他客户端代码仍然会中断,因为它们会在遇到意外的属性名称时以某种方式失败。

为了在 v2 中解决这个问题,我们正在考虑对每个响应中的字段进行随机重新排序。这将强制客户端按名称而不是按位置索引字段。

此外,我们正在考虑为每个响应添加一个随机命名的字段。这将迫使客户忽略他们不认识的字段。

虽然这听起来有些笨拙,但它确实具有我们能够添加新字段的优势,并且知道这不会破坏任何客户端是安全的。这意味着我们可以在同一个 URL 上发布对 v2.1、v2.3 等的兼容更新,这意味着我们只需要维护和支持较少数量的 API 版本。

另一种方法是在新的 URL 上发布破坏兼容性的 v3、v4,这意味着我们将不得不维护和支持许多不兼容的 API 版本,这将使我们变得更薄一些。

这是一个坏主意,如果是,为什么?我应该考虑其他类似的想法吗?

更新:前几个回复指出,如果我记录了问题(即在文档中指出可能会添加或重新排序字段),那么当我随后添加或重新排序字段时,如果客户端代码中断,我将不再受到责备。遗憾的是,我认为这对我们来说不是一个合适的选择:许多组织依赖我们 API 的功能来进行具有重大财务影响的实际交易。这些组织不以技术为导向——在客户端的最终实现涵盖了整个技术熟练度范围。我们已经做到了记录可能在 v1 的文档中添加或重新排序的字段,这显然不起作用,因为现在我们不得不发布 v2,因为许多客户,由于缺乏时间、经验或能力,仍然编写了中断的代码当我们添加新字段时。如果我现在要向界面添加字段,它会破坏十几个不同公司的界面给我们,这意味着他们(和我们)每分钟都在流血。如果我拒绝恢复更改或修复它,说“他们应该阅读文档!”,那么我很快就会失业,这是正确的。我们可能会尝试教育“失败”的合作伙伴,但这注定会失败,因为随着我们的不断发展,问题每个月都会变得越来越大。我的问题是,我是否可以系统地解决整个问题,防止这种情况发生,无论客户尝试做什么?如果我建议的技术可行,我为什么不使用它们?为什么其他人不使用它们?

4

2 回答 2

1

如果您希望您的媒体类型是“可进化的”,请在文档中明确说明这一点。同样,如果不能保证字段的放置顺序,也要明确说明。如果您为 API 提供示例代码,请确保它不依赖于字段排序。

但是,即使假设您必须维护不同版本的媒体类型,您也不必对 URI 进行版本控制。REST 使您能够维护与版本无关的相同 URI,但使用 HTTP 内容协商(通过AcceptContent-Type标头)在同一 URI 上提供不同的有效负载。

因此,任何不明确希望接受您的新 v2/v3/etc 编码的客户端都不会得到它。默认情况下,您可以使用原始字段排序返回旧的 v1 编码,所有这些脆弱的客户端应用程序都可以正常工作。但是,新的客户端开发人员会知道(感谢您的文档)表明Accept他们愿意并且能够看到新字段并且他们不关心他们的订单。最重要的是,您可以(并且应该)始终使用相同的 URI。请记住 - 像这样的不同有效负载只是相同底层资源的不同表示,因此 URI应该是相同的。

于 2012-02-08T03:57:28.857 回答
1

我决定最大限度地使用所描述的技术。我没有听到任何反对他们对我有用的反对意见。Brian 的回答,关于为不同的 API 版本重新使用相同的 URI,是一个可靠且备受赞赏的补充想法(赞成),但我不能授予它“最佳答案”,因为它没有达到核心我原来的问题。

于 2012-06-12T13:11:10.663 回答