RESTful API如何進行版本控制

本文將幫助您理解為什么需要版本控制,以及如何對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

image.png

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

image.png

通過媒體類型進行版本控制

最后一種版本控制方法是在請求中使用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

image.png

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

image.png

影響版本選擇的因素

以下因素影響版本控制的選擇

  • URI 污染 - URL版本和請求參數(shù)版本控制會污染URI空間。
  • 濫用請求頭 - Accept 請求頭并不是為版本控制而設計的抓谴。
  • 緩存 - 如果你使用基于頭的版本控制,我們不能僅僅基于URL緩存仰泻,你需要考慮特定的請求頭我纪。
  • 是否能在瀏覽器直接執(zhí)行 ? - 如果您有非技術消費者丐吓,那么基于URL的版本將更容易使用,因為它們可以直接在瀏覽器上執(zhí)行术健。
  • API文檔 - 如何讓文檔生成理解兩個不同的url是同一服務的版本荞估?

事實上稚新,并沒有完美的版本控制解決方案,你需要根據(jù)項目實際情況進行選擇飞醉。

下面列表展示了主要API提供商使用的不同版本控制方法:

  • 媒體類型的版本控制

    • Github
  • 自定義Header

    • Microsoft
  • URI路徑

    • Twitter缅帘,百度,知乎
  • 請求參數(shù)控制

    • Amazon
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末逗栽,一起剝皮案震驚了整個濱河市失暂,隨后出現(xiàn)的幾起案子弟塞,更是在濱河造成了極大的恐慌,老刑警劉巖想罕,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件按价,死亡現(xiàn)場離奇詭異楼镐,居然都是意外死亡往枷,警方通過查閱死者的電腦和手機错洁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門屯碴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人忱叭,你說我怎么就攤上這事今艺⌒槎校” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長铲掐。 經(jīng)常有香客問我,道長豪椿,這世上最難降的妖魔是什么携栋? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任婉支,我火速辦了婚禮向挖,結果婚禮上,老公的妹妹穿的比我還像新娘跟畅。我一直安慰自己溶推,他們只是感情好蒜危,可當我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布辐赞。 她就那樣靜靜地躺著占拍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪表牢。 梳的紋絲不亂的頭發(fā)上贝次,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天敲茄,我揣著相機與錄音堰燎,去河邊找鬼。 笑死赊淑,一個胖子當著我的面吹牛陶缺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播饱岸,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼罐栈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起荠诬,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤柑贞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后棠众,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體闸拿,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡新荤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年篱瞎,在試婚紗的時候發(fā)現(xiàn)自己被綠了俐筋。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片澄者。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡闷哆,死狀恐怖单起,靈堂內(nèi)的尸體忽然破棺而出劣坊,到底是詐尸還是另有隱情嘀倒,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布局冰,位于F島的核電站测蘑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏康二。R本人自食惡果不足惜碳胳,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望沫勿。 院中可真熱鬧挨约,春花似錦、人聲如沸产雹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蔓挖。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背咽扇。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留怎憋,地道東北人铸鹰。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓剖毯,卻偏偏與公主長得像擂达,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子穗熬,可洞房花燭夜當晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 做RESTful開放平臺棍掐,一方面其API變動越少掘殴, 對API調(diào)用者越有利;另一方面病瞳,沒有人可以預測未來设易,系統(tǒng)在發(fā)展...
    FrancisSoung閱讀 2,038評論 2 5
  • 我們假設API接口的域名名為api.tp5.com掘而,并且以兩個版本v1和v2為例(注意知染,版本號僅為主版本止潘,小版本應...
    進擊的PHPer閱讀 1,380評論 0 0
  • 服務版本控制: 借助header:Accept 和 header: ContentType 實現(xiàn) For exam...
    BenjaminCool閱讀 144評論 0 0
  • 服務API的版本控制歷來沒有一個完美的解決方案档痪,本篇列出了業(yè)界常見的三類API版本控制方案困后,每一類中又有1到2種實...
    一一道長一一閱讀 4,155評論 0 5
  • 推薦指數(shù): 6.0 書籍主旨關鍵詞:特權趾盐、焦點秩冈、注意力丹锹、語言聯(lián)想、情景聯(lián)想 觀點: 1.統(tǒng)計學現(xiàn)在叫數(shù)據(jù)分析,社會...
    Jenaral閱讀 5,721評論 0 5