写点什么

REST 及其版本控制

  • 2010-06-17
  • 本文字数:2048 字

    阅读完需:约 7 分钟

Ganesh Prasad 最近思考的问题是与 REST 相关的最棘手的问题之一:基于 REST 架构的服务版本控制。Ganesh 通过一个示例说明:

假设有一个资源,它的标识是这样的,“/customers/1234”。人们通过 PUT 修改这个资源的状态。[但是]REST 如何处理 PUT 对应的业务逻辑的变更呢?

因为无法通过修改操作名(如,指定 PUTv2)的方式标识服务的业务逻辑发生的变化,一种可能的做法是修改 PUT 使用的 URL,与此同时维护原有的资源标识,Ganesh 描述到:

如 PUT /customers/v2/1234,这不同于客户端的原有标识 /customers/1234。

该方法类似于 Peter Williams 在几年前谈到,而且其他人甚至在更早就谈到的反模式。Peter 在 2008 年如是说:

我非常痛恨这种方法,其隐含的意思是一个版本的 API 与另一版本的 API 表征不同的资源。它迫使客户端作出进退两难的选择,不是同时支持多版本的 API,就是打破 REST 的核心限制之一。例如,一个 V1 版 API 的客户保存了 URL 引用(该 URL 中包括版本标识),一段时间后客户端更新到新版的 API。 此时,客户端支持该 API 的多个版本,因为所有之前保存的 URI 全部指向旧版本的 API,或者必须要将这些 URI 转接到新版 API。URI 转接打破了 REST 的将多媒体当作应用程序状态引擎(HATEOAS)的限制,而支持多版本的 API 是维护工作中的噩梦。

Peter 建议使用定制媒体类型与(最终必将发生的非向后兼容性变更的)内容协商的结合进行版本控制。

该方法的确会导致新建媒体类型,但是媒体类型是低成本的,所以我们可以,而且应该,需要多少媒体类型就创建多少。如果能正确使用,内容协商可用于解决 REST/HTTP 服务接口的版本控制问题。

但是,回到 Ganesh 以及最初的修改 URL 的方法,他也不同意这种方法。

首先,如果认为只有两处(动词以及资源)可以存放业务逻辑的不同版本,那就是一个错误。第三处是所提交的数据中……但此例仅仅引发了我对版本控制根本的探究。

进而他提出了 REST 与 SOA 所需的版本控制的问题,它问道,首先版本控制是什么,其次为什么需要它?

我认为服务版本控制是一种机制,它使我们能够以消费者可见的方式同时维护两组或多组业务逻辑的版本。

首先他问道,为什么要对消费者可见,如果服务能够区别不同的消费者类型,那么它就能在内部为不同的调用者(客户端 / 消费者)应用不同的业务逻辑?接着它又进一步提出问题:我们为什么要同时维护不同版本的业务逻辑呢?

一个有趣(又迂回)的答案是,业务逻辑通常需要对消费者可见,所以新版的业务逻辑也需要以消费者可见的方式与其旧版本进行区别。这往往被描述成是对旧消费者的支持,比如,消费者在某方面依赖于旧版本的业务逻辑的服务消费者。

支持旧客户的目的是确保现有的契约和 SLA 不会因为服务的(悄然)更新而被破坏。这就引出了 Ganesh 的又一问题,版本控制的问题的解决办法可否不通过使用显式的版本,而在对具体实施细节进行抽象时找到呢?也许服务契约太细节了以至于在变更发生时显得脆弱。(类似于过去 SOA 背后的一个重要原则,松耦合与紧耦合的思想)

Ganesh 接着通过一个例子描述了如何使用这种方法解决版本控制的问题。在该例中,一个虚构的开发人员在已有服务消费者的情况下悄悄地完成了对服务的业务逻辑的变更。

第一个问题是,新的业务逻辑能否应用于所有的消费者,或者我们是否需要跟踪“旧”消费者并继续为他们保留旧的业务逻辑?如果我们能够为所有消费者升级到新的业务逻辑,那是当然没有任何问题的。接口继续保持不变,客户端应用程序将数据 POST 到相同的 URI,请求接着被转发到新建资源的地址……所应用的业务逻辑是全新的,但是客户端不会从接口中感知到变化……

但是,当然也有可能根本无法做到这样,这时就需要维护业务逻辑的多个版本。Ganesh 接着描述了这种情况发生的几个可能的原因:

  • 客户端应用程序应该提交的数据有变化,这种变更不可避免地要让消费者知情,而且不得不使用新契约进行交互。
  • 另一商业原因是区分两类客户,也许是要奖励长期的客户,为他们提供更好的服务,不过该变化不会从客户端提交的数据中察觉出来。
  • 客户端应用程序可能“了解”旧版本的服务行为并依赖于这些行为,这种情况下,需要使用新的版本已避免 d 对遗留客户造成破坏。

Ganesh 认为,第三种情况是人为的,它意味着通过消费者和服务实现之间的显式依赖关系破坏了服务的松耦合性。

相反,第一种和第二种情况都有相应的解决方案。如果由客户端提交的数据要发生改变,那么这本身就是一种区别新消费者与旧消费者的方式,从而可以为他们提供不同的业务逻辑。换言之,我们仅需告诉新消费者他们需要对 POST 的数据作出的修改。旧消费者什么都不用做。此外,如果我们能够在某种程度上得知消费者是旧消费者,那么,即使它既提交的数据没有明显的区别,我们也能透明地应用不同的业务逻辑。

他这样总结自己的观点……

服务的版本不是接口细节,而往往是在接口中泄漏的实现细节。

服务的版本控制问题是许多领域里的常见话题,不仅仅是REST。然而,Ganesh 坚信REST 为该问题提供了更好,更自然的解决方法。


查看英文原文: REST and versioning

2010-06-17 04:484312
用户头像

发布了 184 篇内容, 共 79.2 次阅读, 收获喜欢 8 次。

关注

评论

发布
暂无评论
发现更多内容

面试官:vue2和vue3的区别有哪些?

bb_xiaxia1998

Vue

ReactDOM.render在react源码中执行之后发生了什么?

flyzz177

React

redhat运维-ftp服务故障

阿柠xn

Linux 运维 ftp 11月月更

面试官让你说说react状态管理?

beifeng1996

React

一份vue面试知识点梳理清单

bb_xiaxia1998

Vue

React Context源码是怎么实现的呢

flyzz177

React

能否手写vue3响应式原理-面试进阶

helloworld1024fd

JavaScript

算法基础:离散化及模板详解

timerring

算法 11月月更 离散化

数据结构学习笔记(二)

lxmoe

数据结构 学习笔记 11月月更

Apache Pulsar 社区年度峰会 Pulsar Summit Asia 2022 即将召开

腾源会

大数据 开源

我的react面试题整理2(附答案)

beifeng1996

React

React源码分析1-jsx转换及React.createElement

goClient1992

React

React源码分析(二)渲染机制

goClient1992

React

React源码分析(三):useState,useReducer

goClient1992

React

前端vue面试题

bb_xiaxia1998

Vue

细说react源码中的合成事件

flyzz177

React

python中类与对象的动态性,混入机制

乔乔

11月月更

数据预处理和特征工程-特征选择-Wrapper包装法

烧灯续昼2002

Python 机器学习 算法 sklearn 11月月更

记一次京东前端面试被问到的题目

helloworld1024fd

JavaScript

产品待办列表PBL与产品需求文档PRD的本质区别

ShineScrum捷行

Scrum PRD 产品待办列表 PBL 产品需求文档

数据结构学习笔记(一)

lxmoe

数据结构 学习笔记 11月月更

企业级 Angular 应用路由路径自定义配置和开发的案例分享

汪子熙

typescript 前端开发 angular Web应用 11月月更

Wallys/IPQ4018/IPQ4028 2x2 2.4Ghz 2x2 5Ghz Industrial WIFI5 router/Support 11ABGN/AC

Cindy-wallys

IPQ4018 IPQ4028 2.4G&5G

Java注解与原理分析

Java 架构

腾讯前端高频手写面试题

helloworld1024fd

JavaScript

手撕常见JS面试题

helloworld1024fd

JavaScript

Java中的BigDecimal比较大于小于等于,四舍五入保留几位(setScale方法详解),加减乘除取余

共饮一杯无

Java BigDecimal 11月月更

Wallys/ DR9074-6E QCN9074 WIFI 6E 802.11AX 4X4 6GHz/ industrial M.2 card / DR9074-6E(PN02.7)

Cindy-wallys

m.2 QCN9074 WIFI 6e

关于软件物料清单(SBOM),你所需要了解的一切

SEAL安全

安全 软件物料清单 SBOM

Vue.$nextTick的原理是什么-vue面试进阶

bb_xiaxia1998

Vue

荣耀开发者大会预约有礼

荣耀开发者服务平台

开发者 手机 开发者大会 荣耀 honor

REST 及其版本控制_SOA_Mark Little_InfoQ精选文章