你們好,我是飄渺!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源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。