你们好,我是飘渺!java
在实际项目开发中咱们常常须要对接口进行版本管理。那今天咱们就来聊聊为何须要版本控制,以及如何对REST API进行版本控制。咱们将讨论4种版本控制的方法,并比较不一样的方法。程序员
经过此文您将学到web
-
为何咱们须要对RESTful API 进行版本控制?spring
-
可用的版本控制有哪些?json
-
如何实现基于 Restful 的版本控制?api
为何咱们须要对RESTful API进行版本化
最好的版本控制方法是不进行版本控制。只要不须要版本控制,就不要版本控制。浏览器
“构建向后兼容的服务,以便尽量避免版本控制!缓存
”
然而,在许多状况下咱们都须要进行版本控制,然咱们看看下面具体的例子:微信
最初,你有个这个版本的Student服务,返回数据以下:架构
{ "name": "Bob Charlie" }
后来,您但愿将学生的名字拆分,所以建立了这个版本的服务。
{ "name": { "firstName": "Bob", "lastName": "Charlie" } }
您能够从同一个服务支持这两个请求,可是随着每一个版本的需求多样化,它会变得愈来愈复杂。
在这种状况下,版本控制就成必不可少,强制性的了。
接下来让咱们建立一个简单的SpringBoot的maven项目,并理解对 RESTful 服务进行版本控制的4种不一样方法。
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
几个用于实现版本控制的Bean
第一个版本的 Bean
@Data @AllArgsConstructor public class StudentV1 { private String name; }
第二个版本的 Bean
@Data public class StudentV2 { private Name name; }
StudentV2使用的Name实体
@Data @AllArgsConstructor public class Name { private String firstName; private String lastName; }
Restful 版本控制的方法
咱们但愿建立两个版本的服务,一个返回 StudentV1,另外一个返回 StudentV2。
让咱们来看看建立相同服务版本的4种不一样方法。
经过 URI 进行版本控制
@RestController public class StudentUriController { @GetMapping("v1/student") public StudentV1 studentV1() { return new StudentV1("javadaily"); } @GetMapping("v2/student") public StudentV2 studentV2() { return new StudentV2(new Name("javadaily", "JAVA日知录")); } }
请求:http://localhost:8080/v1/student
响应:{"name":"javadaily"}
请求:http://localhost:8080/v2/student
响应:{"name":{"firstName":"javadaily","lastName":"JAVA日知录"}}
经过请求参数进行版本控制
版本控制的第二种方法是使用请求参数来区分版本。请求示例以下所示:
-
http://localhost:8080/student/param?version=1
-
http://localhost:8080/student/param?version=2
实现方式以下:
@RestController public class StudentParmController { @GetMapping(value="/student/param",params = "version=1") public StudentV1 studentV1() { return new StudentV1("javadaily"); } @GetMapping(value="/student/param",params = "version=2") public StudentV2 studentV2() { return new StudentV2(new Name("javadaily", "JAVA日知录")); } }
请求:http://localhost:8080/student/param?version=1
响应:{"name":"javadaily"}
请求:http://localhost:8080/student/param?version=2
响应:{"name":{"firstName":"javadaily","lastName":"JAVA日知录"}}
经过自定义Header进行版本控制
版本控制的第三种方法是使用请求头来区分版本,请求示例以下:
-
http://localhost:8080/student/header
-
headers=[X-API-VERSION=1]
-
-
http://localhost:8080/student/header
-
headers=[X-API-VERSION=2]
-
实现方式以下所示:
@RestController public class StudentHeaderController { @GetMapping(value="/student/header",headers = "X-API-VERSION=1") public StudentV1 studentV1() { return new StudentV1("javadaily"); } @GetMapping(value="/student/header",headers = "X-API-VERSION=2") public StudentV2 studentV2() { return new StudentV2(new Name("javadaily", "JAVA日知录")); } }
下图展现了咱们如何使用Postman执行带有请求头的Get请求方法。
请求:http://localhost:8080/student/header
header:X-API-VERSION = 1

请求:http://localhost:8080/student/header
header:X-API-VERSION = 2

经过媒体类型进行版本控制
最后一种版本控制方法是在请求中使用Accept Header,请求示例以下:
-
http://localhost:8080/student/produce
-
headers=[Accept=application/api-v1+json]
-
-
http://localhost:8080/student/produce
-
headers=[Accept=application/api-v2+json]
-
实现方式以下:
@RestController public class StudentProduceController { @GetMapping(value="/student/produce",produces = "application/api-v1+json") public StudentV1 studentV1() { return new StudentV1("javadaily"); } @GetMapping(value="/student/produce",produces = "application/api-v2+json") public StudentV2 studentV2() { return new StudentV2(new Name("javadaily", "JAVA日知录")); } }
下图展现了咱们如何使用Postman执行带有请求Accept的Get方法。
请求:http://localhost:8080/student/produce
header:Accept = application/api-v1+json

请求:http://localhost:8080/student/produce
header:Accept = application/api-v2+json

影响版本选择的因素
如下因素影响版本控制的选择
-
URI 污染 - URL版本和请求参数版本控制会污染URI空间。
-
滥用请求头 - Accept 请求头并非为版本控制而设计的。
-
缓存 - 若是你使用基于头的版本控制,咱们不能仅仅基于URL缓存,你须要考虑特定的请求头。
-
是否能在浏览器直接执行 ? - 若是您有非技术消费者,那么基于URL的版本将更容易使用,由于它们能够直接在浏览器上执行。
-
API文档 - 如何让文档生成理解两个不一样的url是同一服务的版本?
“事实上,并无完美的版本控制解决方案,你须要根据项目实际状况进行选择。
”
下面列表展现了主要API提供商使用的不一样版本控制方法:
-
媒体类型的版本控制
-
Github
-
-
自定义Header
-
Microsoft
-
-
URI路径
-
Twitter,百度,知乎
-
-
请求参数控制
-
Amazon
-
好了,今天的文章就到这里了,但愿能对你有所帮助。
最后,我是飘渺Jam,一名写代码的架构师,作架构的程序员,期待您的关注。
关注即送10个G的教学视频,你还在等什么,还不赶忙上车?
本文分享自微信公众号 - JAVA日知录(javadaily)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。