在本文中,Stu Charlton 归纳了 RESTful 服务版本控制的多种选择,他在本书的前言中 这样说道“这些概念是很难描述的棘手概念,我实在不想以这样的主题写一本小书”。他把各种版本控制的问题总结成两类:数据版本控制,用于控制资源本身,那么,对于任何给定资源,跟踪其状态就变得可能; 语言版本控制,指得是协议本身,即展现。
URI 版本控制 […] 是一种设计决定,用于当资源不随时间的变迁而变化时,我们为状态的改变创建新资源(类似于管理数据库中的时间序列数据)。
语言扩展或版本控制,相反,状态不改变,而是数据的展现被更改。
Stu 赞同 David Orchard 所著的关于版本控制能力策略的 W3C TAG 的 草案,该草案阐明了向后,向前以及不兼容变更的复杂之处。他说,“语言的扩展需要深思”,他还强调:
规则#1:倾向于以向前且 / 或向后兼容的方式对语言进行扩展。版本标识器是表示不兼容变更的最后的一招。
他用下表对文档进行了归纳:
消费者 生产者 向后兼容 - 查找版本通知
- 替换或二者相安无事
- 通过带外通道或链接进行版本通知
向前兼容 - 必须接受未知
-
如果保持状态,必须保留未知
-
版本标识替换模型
-
媒体类型规范显示定义消费者向前兼容 期望(以及 / 或者使用机器可读的模式去表示向前兼容的扩展域)。
不兼容 - 检查版本标识
- 二者相安无事或断裂替换
接着,他定义了本表中使用的一些术语,如版本通知,替换,相安无事,版本标识 等。此外,他还定义了生产者和消费者之间如何处理在不同兼容场景的“语言”中出现的未知元素。他检视了多种提供版本标识的策略,并针对这些策略的应用,给出了他个人的优先级顺序。
媒体类型内容中的版本标识
这样的例子有很多,如 HTML DOCTYPE,XMLNS 的某些使用或 PDF 文档中的某个版本标识。[…] 这是大多数 Web 媒体类型长期以来的工作方式,成功程度各有不同。但是,要注意,那些格式都是经过考虑了向前兼容的长远的设计定义的。
MIME 类型中的版本标识
[…] 这里的好处是它支持互不相干的版本控制且不会影响到 URI 空间。 […但是…] 这种做法带有明显的逃避多媒体的意味并试图把问题推到网络架构 (HTTP 以及 / 或者 URI)的另一层次。如 application/vnd.mytype;version=2
URI 中的版本标识
很明显,当资源本身的语义发生变化时我们是在铸造 URI。所以,如果它们随语言而修改,那我们铸造了新的 URI,如 http://example.com/data/v1/po/123
另一个问题是书签,在数据系统中它实际上是“外键”。任何有关系型数据库背景的人都知道主键实际上不会改变,因为要把其更改传播到外键是很昂贵的工作。
他推荐阅读 Subbu Allamaraju 所著的《RESTful Web Services Cookbook》一书的第 13 章并从中学习更多相关的知识。他也给自己的文章做了如下总结:
- 更愿意使用扩展的,向前以及向后兼容的语言以及替换方法。注意 W3C TAG 关于版本标识的观点。
- 当你在 URI 中使用版本标识是要审慎,因为好的 URI 是不会更改的。
- 对于相安无事的部署,始终在你的媒体类型或链接关系中包含一个块,用于指向新 / 旧版本,并在消费者更新它的缓存值是延迟更新引用。使用永久的转发使绑定到旧的语言版本的 URI 退役。
- 如果资源语义发生变化,对 URI 进行版本控制,但是对待消费者要礼遇,要确保通往新 / 旧资源的链接。
Stu 的文章尝试了把所有 RESTful 服务的版本控制的解决方案中的元素结合到一起,然而,在这些策略间关于谁是正确的选择的争论却一直没有停止过。
评论