rest - 强制 web api 消费者接受响应中的新字段

我正在创建现有 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,因为很多客户,由于时间不够或经验或能力,仍然编写在我们添加新字段时中断的代码。如果我现在向界面添加字段,它会破坏十几个不同公司对我们的界面,这意味着他们(和我们)每分钟都在流血。如果我拒绝恢复更改或修复它,说“他们应该阅读文档!”,那么我很快就会失业,这是正确的。我们可能会尝试教育“失败”的合作伙伴,但这注定要失败,因为随着我们的不断发展,问题每个月都会变得更大。我的问题是,无论客户试图做什么,我能否系统地阻止整个问题的发生,防止这种情况发生?如果我建议的技术可行,我为什么不使用它们呢?为什么其他人不使用它们?

最佳答案

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

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

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

https://stackoverflow.com/questions/9176910/

相关文章:

c# - 在 IIS 服务器上发布 C# 控制台应用程序

ruby-on-rails - 如何从 Rails 中的模型继承,其中一种类型在不交织的情况下扩展另

.net - 如何设置 "user cannot change password"AD属性

google-chrome - 使用 TFS/NUnit 通过构建过程执行时,使用 Google C

cuda - 在 Cmake 项目中指定 openmp CUDA 标志

python - subprocess.Popen 不是线程安全的?

sql - 查找某个点之后或之前的值

php - php中var-export函数的反义词是什么?

hive - 使用 Apache Hive session 化我的日志数据的更好方法?

mysql - 导入mysql数据中断,如何恢复?