本文將幫助您理解為什么需要版本控制,以及如何對REST API進行版本控制篱昔。我們將討論4種版本控制的方法每强,并比較不同的方法。
您將學到
- 為什么我們需要對RESTful API 進行版本控制?
- 可用的版本控制有哪些?
- 如何實現(xiàn)基于 Restful 的版本控制?
為什么我們需要對RESTful API進行版本化
最好的版本控制方法是不進行版本控制州刽。只要不需要版本控制空执,就不要版本控制。
構建向后兼容的服務穗椅,以便盡可能避免版本控制辨绊!
然而,在許多情況下我們都需要進行版本控制匹表,然我們看看下面具體的例子:
最初门坷,你有個這個版本的Student服務宣鄙,返回數(shù)據(jù)如下:
{
"name": "Bob Charlie"
}
后來,您希望將學生的名字拆分默蚌,因此創(chuàng)建了這個版本的服務。
{
"name": {
"firstName": "Bob",
"lastName": "Charlie"
}
}
您可以從同一個服務支持這兩個請求敏簿,但是隨著每個版本的需求多樣化惯裕,它會變得越來越復雜蜻势。
在這種情況下,版本控制就成必不可少够傍,強制性的了冕屯。
接下來讓我們創(chuàng)建一個簡單的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>
幾個用于實現(xiàn)版本控制的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 版本控制的方法
我們希望創(chuàng)建兩個版本的服務念颈,一個返回 StudentV1榴芳,另一個返回 StudentV2窘面。
讓我們來看看創(chuàng)建相同服務版本的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日知錄"}}
通過請求參數(shù)進行版本控制
版本控制的第二種方法是使用請求參數(shù)來區(qū)分版本酣难。請求示例如下所示:
http://localhost:8080/student/param?version=1
http://localhost:8080/student/param?version=2
實現(xiàn)方式如下:
@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進行版本控制
版本控制的第三種方法是使用請求頭來區(qū)分版本,請求示例如下:
-
http://localhost:8080/student/header
- headers=[X-API-VERSION=1]
-
http://localhost:8080/student/header
- headers=[X-API-VERSION=2]
實現(xiàn)方式如下所示:
@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日知錄"));
}
}
下圖展示了我們?nèi)绾问褂肞ostman執(zhí)行帶有請求頭的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]
實現(xiàn)方式如下:
@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日知錄"));
}
}
下圖展示了我們?nèi)绾问褂肞ostman執(zhí)行帶有請求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版本和請求參數(shù)版本控制會污染URI空間。
- 濫用請求頭 - Accept 請求頭并不是為版本控制而設計的抓谴。
- 緩存 - 如果你使用基于頭的版本控制,我們不能僅僅基于URL緩存仰泻,你需要考慮特定的請求頭我纪。
- 是否能在瀏覽器直接執(zhí)行 ? - 如果您有非技術消費者丐吓,那么基于URL的版本將更容易使用,因為它們可以直接在瀏覽器上執(zhí)行术健。
- API文檔 - 如何讓文檔生成理解兩個不同的url是同一服務的版本荞估?
事實上稚新,并沒有完美的版本控制解決方案,你需要根據(jù)項目實際情況進行選擇飞醉。
下面列表展示了主要API提供商使用的不同版本控制方法:
-
媒體類型的版本控制
- Github
-
自定義Header
- Microsoft
-
URI路徑
- Twitter缅帘,百度,知乎
-
請求參數(shù)控制
- Amazon