rest api_REST API的演变
rest api
每個開發人員都以某種方式接觸到API 。 要么為一家大公司集成一個主要系統,或者使用最新的圖形庫生成一些精美的圖表,要么直接與他喜歡的編程語言進行交互。 事實是,API無處不在! 它們實際上代表了當今Internet的基本構建塊,在不同系統和設備之間發生的數據交換過程中扮演著重要角色。 從您手機上的簡單天氣小部件到您在網上商店中執行的信用卡付款,如果這些系統無法通過調用彼此的API相互通信,那么所有這些都是不可能的。
因此,隨著連接到互聯網的異構設備生態系統的不斷發展,API提出了一系列嚴峻的挑戰。 盡管它們必須繼續以可靠和安全的方式運行,但它們還必須與所有這些設備兼容,從手表到數據中心中最先進的服務器。
REST來解救
用于構建此類API的最廣泛使用的技術之一就是所謂的REST API。 這些API旨在提供異構系統之間通用且標準化的通信方式。 由于它們嚴重依賴于標準的通信協議和數據表示(例如HTTP,XML或JSON),因此很容易在大多數編程語言上提供客戶端實現,從而使其與絕大多數系統和設備兼容。
因此,盡管這些REST API可以與大多數設備和技術兼容,但它們也必須不斷發展。 演化的問題是,有時您必須保持與舊客戶端版本的復古兼容性。
讓我們建立一個例子。
讓我們想象一個約會系統,在該系統中您具有一個用于創建和檢索約會的API。 為簡化起見,讓我們想象一下約會對象和日期以及來賓姓名。 像這樣:
public class AppointmentDTO {public Long id;public Date date;public String guestName; }一個非常簡單的REST API如下所示:
@Path("/api/appointments") public class AppointmentsAPI {@GET@Path("/{id}")public AppointmentDTO getAppointment(@PathParam("id") String id) { ... }@POSTpublic void createAppointment(AppointmentDTO appointment) { ... }}讓我們假設這個簡單的簡單API可以正常工作,并且可以在允許預訂和顯示約會的手機,平板電腦和各種網站上使用。 到目前為止,一切都很好。
在某個時候,您認為開始收集有關約會系統的一些統計信息將非常有趣。 為了簡單起見,您只想知道誰是預訂次數最多的人。 為此,您需要將訪客之間關聯起來,并決定需要為每個訪客添加唯一的標識符。 讓我們使用電子郵件。 因此,現在您的對象模型將如下所示:
public class AppointmentDTO {public Long id;public Date date;public GuestDTO guest; }public class GuestDTO {public String email;public String name; }因此,我們的對象模型稍有變化,這意味著我們將不得不在api上調整業務邏輯。
問題
盡管使API適應存儲和檢索新對象類型應該是輕而易舉的事,但問題是您當前的所有客戶端都在使用舊模型,并且將繼續這樣做直到更新。 可以說您不必為此擔心,客戶應該更新到較新的版本,但事實是您不能真正地從頭到尾進行更新。 始終會有一個時間窗口,您必須保持兩個模型都運行,這意味著您的api必須是復古兼容的。
這是您的問題開始的地方。
回到我們的示例,在這種情況下,這意味著我們的API將必須處理兩個對象模型,并能夠根據客戶端存儲和檢索那些模型。 因此,讓我們將guestName添加回我們的對象中,以保持與舊客戶端的兼容性:
public class AppointmentDTO {public Long id;public Date date;@Deprecated //For retro compatibility purposespublic String guestName;public GuestDTO guest; }請記住,關于API對象的一個??好的經驗法則是,永遠不要刪除字段。 添加新字段通常不會破壞任何客戶端實現(假設它們遵循忽略新字段的良好經驗法則),但是刪除字段通常是噩夢之路。
現在,為了保持API兼容,有幾種不同的選擇。 讓我們看一些替代方案:
- 復制 :單純。 為新客戶創建一種新方法,并讓舊客戶使用相同的方法。
- 查詢參數 :引入一個標志來控制行為。 諸如useGuests = true之類的東西。
- API版本控制 :在您的URL路徑中引入一個版本,以控制要調用的方法版本。
因此,所有這些替代方案都有其優缺點。 盡管復制很簡單,但是它可以輕松地將您的API類變成一碗重復的代碼。
可以(并且應該)將查詢參數用于行為控制(例如,將分頁添加到列表中),但是我們應避免將其用于實際的API演變,因為這些參數通常是永久性的,因此您不希望使用對于消費者來說是可選的。
版本控制似乎是個好主意。 它提供了一種開發API的干凈方法,它使舊客戶端與新客戶端保持隔離,并為您在API使用壽命期間發生的各種更改提供了通用基礎。 另一方面,它也引入了一些復雜性,特別是如果您在不同版本上有不同的調用時。 您的客戶最終將不得不通過升級調用而不是API來自己管理API的演變。 就像您沒有升級庫到下一個版本,而是只升級了該庫的某個類。 這很容易變成版本夢night……
為了克服這個問題,我們必須確保我們的版本涵蓋整個API。 這意味著我應該能夠使用/ v2來調用/ v1上的每個可用方法。 當然,如果v2上存在給定方法的較新版本,則應在/ v2調用上運行它。 但是,如果給定方法在v2中沒有更改,我希望可以無縫調用v1版本。
基于繼承的API版本控制
為了實現這一點,我們可以利用Java對象的多態功能。 我們可以以分層的方式構建API版本,以便較新的版本可以覆蓋較舊的版本,而對未更改方法的較新版本的調用可以無縫地回退到較早的版本。
因此,回到我們的示例,我們可以構建一個新版本的create方法,以便API如下所示:
@Path("/api/v1/appointments") //We add a version to our base path public class AppointmentsAPIv1 { //We add the version to our API classes@GET@Path("/{id}")public AppointmentDTO getAppointment(@PathParam("id") String id) { ... }@POSTpublic void createAppointment(AppointmentDTO appointment) { //Your old way of creating Appointments only with names} }//New API class that extends the previous version @Path("/api/v2/appointments") public class AppointmentsAPIv2 extends AppointmentsAPIv1 {@POST@Overridepublic void createAppointment(AppointmentDTO appointment) { //Your new way of creating appointments with guests} }因此,現在我們有2個工作版本的API。 盡管所有尚未升級到新版本的舊客戶端將繼續使用v1,并且不會看到任何更改,但您的所有新客戶現在都可以使用最新的v2。 請注意,所有這些調用均有效:
| GET /api/v1/appointments/123 | 將在v1類上運行getAppointment |
| GET /api/v2/appointments/123 | 將在v1類上運行getAppointment |
| POST /api/v1/appointments | 將在v1類上運行createAppointment |
| POST /api/v2/appointments | 將在v2類上運行createAppointment |
這樣,任何想要開始使用最新版本的使用者都只需將其基本URL更新為相應的版本,并且所有API都將無縫轉換到最新的實現,同時保持舊的不變。
警告
出于敏銳的眼光,這種方法立即引起了警告。 如果您的API由十分之幾的不同類組成,那么即使您實際上沒有任何更改,較新的版本也會暗示將它們全部復制為較高版本。 這是一些可以自動生成的樣板代碼。 仍然很煩。
盡管沒有快速的方法可以解決此問題,但是使用接口可能會有所幫助。 除了創建新的實現類之外,您還可以創建一個新的帶路徑注釋的接口,并在當前的實現類中對其進行實現。 盡管您將不得不為每個API類創建一個接口,但它有點干凈。 它有一點幫助,但仍然是一個警告。
最后的想法
API版本控制似乎是當前的熱門話題。 存在許多不同的觀點和意見,但似乎缺乏標準的最佳實踐。 盡管本文并非旨在提供這樣的內容,但我希望它有助于實現更好的API結構并有助于其可維護性。
最后要說的是羅伯托·科爾特斯 ( Roberto Cortez)鼓勵并允許將此帖子發布在他的博客上。 這實際上是我的第一篇博文,因此請加載大炮并隨意開火。 :)
翻譯自: https://www.javacodegeeks.com/2015/03/rest-api-evolution.html
rest api
總結
以上是生活随笔為你收集整理的rest api_REST API的演变的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑ppt壁纸(电脑壁纸幻灯片)
- 下一篇: 一只手可以拎走的电脑,打造一台8.4L的