微服務構建持久API的7大規則

JFrog傑蛙科技發表於2020-02-11

近年來,微服務架構發展迅速,SparkPost就是早期落地微服務架構公司之一,他們發現落地微服務過程中,不光需要考慮服務發現、服務註冊、服務呼叫跟蹤鏈等等架構問題,也需要重視微服務API的變更管理。微服務的一大特性就是獨立釋出,快速迭代,但前提是足夠穩定,他們在使用微服務構建API的過程中就遇到很多問題:

1.  客戶(微服務使用方)經常反饋API 升級變更後不可用,有時影響範圍不可控,導致該微服務上線延期,甚至線上故障,違背了微服務初衷

2.  API引數變化或返回結果變化而導致客戶端行為不一致,依賴客戶端需要大量重構,團隊不能專注在創新型工作

3.  API 易用性差, 使用方技術棧不統一,各自進行API抽象及封裝,容易出錯

4.  缺少文件及使用引導,需要大量支援工作

5.  閉門造車,產出微服務往往不能滿足需求,執行一段時間就會逐漸廢棄

SparkPost經過多年的探索與實踐,總結了大量最佳實踐,指導他們構建持久穩定的微服務API。現如今,它們的API被成千上萬的客戶使用,包括Pinterest、Zillow和Intercomto,每月傳送超過150億封電子郵件。

在這篇文章中,我將回顧幾個選擇和最佳實踐。

 


七大原則

一、Restful是最好的,但要實用,不需要學究式

首先,也是最重要的一步,我們採取的步驟是決定使用REST作為API。我們的理念是選擇以下三個要素作為我們的API的基礎:。

1.  HTTP : 這包括響應程式碼和運算子。運算子包括POST、GET、PUT和DELETE,它們可以對映到基本CRUD(建立、讀取、更新、刪除)操作。

2.  resources : 這些是HTTP操作人員執行的實體。

3.  JSON (JavaScript物件表示法) : 這是一種通用的資料交換格式。

這三個元素提供了實用REST API所需的一切,包括簡單性、可移植性、互操作性和可修改性。在構建了API之後,使用者可以輕鬆地對其進行整合,而不考慮他們的程式語言,包括C#、PHP和Node。Js, Java,甚至是Shell中的CURL。他們可以不用擔心潛在的技術發展,包括多種微服務。

當我們建立SparkPost API時,我們試著不要太過學究式地使用純粹的REST模型,而是選擇易於使用。下面是兩個可能不遵循RESTful最佳實踐的示例:

1.  GET /api/v1/account?include=usage

2.  POST/api/v1/sending-domains/example.domain.com/verify

第一個示例使用查詢字串引數來過濾實體中返回的內容。在第二個示例中,我們在終端名稱中使用“verify”這個動詞,這可能不符合Restful。我們會討論每個新的用例,並盡力確保它的一致性和易於使用。

 

二、發展進化並管理變化

我們有許多開發人員和團隊在使用我們的API的微服務,並在持續的變更。當工程師確定它已經透過了我們的測試時,我們就會自動將變更部署到生產中。

我們很早就決定讓我們的API在使用慣例和如何管理變更方面保持一致。我們建立了一個治理小組,其中包括代表每個團隊的工程師、產品管理組的成員和CTO。這個組建立了並強制我們遵守的API約定,並且是完全文件化的。

文件化的約定讓我們可以減少不一致,並且更容易定義每個新的端點。以下是我們建立的一些約定:

·  在單詞命名時,URL路徑是帶有連字元的小寫字母,並且區分大小寫。

·  URL查詢引數和JSON欄位也是小寫的下劃線,並且是大小寫敏感的。

·  請求主體中的非預期查詢引數和JSON欄位應該被忽略。

治理組還為如何進行更改以及允許哪些型別的更改設定了基本規則。有一些很好的API更改對使用者是有益的,並且不會破壞它們的整合,包括:

·  一個新的API資源、端點或現有資源上的操作。

·  一個新的可選引數或JSON欄位。

·  JSON響應主體中返回的新欄位。

相反,一個破壞性的變化包括任何可能破壞使用者整合的東西,比如:

·  更改欄位的資料型別。

·  一個新的必需引數或JSON 欄位。

·  刪除現有端點或請求方法。

·  現有資源方法的實質性行為差異,例如將選項的預設值改為“true”

 

三、做任何修改時不要製造破壞 

即使它們是修復bug或不一致的結果,也應該避免發生修改。通常在這種特殊的情況下執行比破壞與客戶端的整合風險更大。如果變化是多樣的,我們會非常謹慎,尋找其他方法來實現我們的目標。有時可以透過簡單地允許使用者透過帳戶設定或API引數更改其行為來實現。

然而,總會有一種情況引入變化對我們使用者的利益勝過任何潛在的不利因素,將引入的變化。但是在這些情況下,我們遵循了這些最佳實踐: 

·  我們分析了API日誌,以瞭解更改可能會影響多少使用者。

·  我們給使用者至少30到60天的提前警告。

·  我們發了一封郵件或發表了一篇部落格文章,裡面包含了關於改變的詳細資訊以及我們為什麼要做這些改變。

·  我們在API文件中提供了升級指導。

 

四、“一個版本”規則

在過去的三年裡,我們對API進行了數千次的修改,現在仍然是第一個版本。我們很早就決定不將API的版本超過第一個版本,因為這樣做會增加不必要的複雜性,從而減慢使用者對我們最新和最強大功能的使用。對API的版本控制也會減緩開發和測試,讓監控變得複雜,讓使用者文件變得混亂。

另外,我們的API沒有版本控制,這意味著我們可以避免圍繞主題的爭論。有三種方法可以實現API的版本,所有這些都有潛在的缺陷:

·  把這個版本放到URL中: 容易做,但是從語義的角度來看是一個不好的選擇,因為這個實體在v1和v2之間沒有變化。

·  新增一個自定義的標題 : 也很容易做,但是語義不強。

·  accept標頭中放置這個版本: 語義強但是最複雜的方法。

 

五、使用客戶端庫來幫助非javascript使用者

我們的一些使用者更喜歡Python、c#、Java或PHP而不是JavaScript。我們透過維護客戶端庫(為其程式碼提供易於使用的函式庫)將API整合到應用程式中,使其快速進行整合。

隨著時間的推移,我們的客戶庫已經發生了變化,我們也做了相應的版本。我們已經瞭解到,在包裝一個不斷增長的API時,抽象是很困難的,所以我們專注於提供一層薄薄的抽象,並使用一些語法快捷方式來簡化我們API的使用。這樣做可以讓我們的使用者快速地訪問我們任何API,並且具有許多靈活性

 

六、“文件優先”的策略

我們將我們的文件視為程式碼,並在編寫或更改一個API程式碼行之前使用它來記錄我們的API更改。這樣做可以幫助我們執行我們的約定,使所有事情保持一致,並保持良好的客戶體驗。它還削減了支援成本。

我們在GitHub中維護我們的文件,這使得技術和非技術使用者可以很容易地做出更改。我們還發現,更容易審查變更的方式。我們使用API Blueprint Markdown格式和Jekyll生成HTML文件,以及一個名為Algolia的強大搜尋服務。這樣做讓我們能夠提供更好的客戶體驗,包括移動裝置。

對於那些不想“滾動升級自己”文件的人來說,我們推薦OpenAPI(以前稱為“Swagger”)、Apiary和API Blueprint。避免使用不適合REST API文件的工具是很重要的。我們建議在文件中包含一個亮橙色的“在Postman中執行”的按鈕,這樣可以很容易地試用一個API,以及成功和失敗場景的例子。

 

七、聽取使用者的意見

最後,我們建議所有開發人員注意他們的使用者的反饋。SparkPost有一個社群Slack的頻道,成千上萬的使用者可以方便地聯絡我們的產品、支援、工程和執行管理團隊的成員。我們也有一個專門的開發人員關係團隊,他們專注於與開發人員社群的合作。所有這些都讓我們能更好傾聽使用者的意見,並將他們的反饋整合到我們的API中。

 

總結

隨著微服務架構的發展,微服務快速增長,有的企業內部運維了超過1000的微服務,且仍在不斷增長,每個微服務包含數十API,如何持續管理微服務API 變化將成為企業的關注點,SparkPost 根據這些規則和最佳實踐,為他們的業務從提供現場電子郵件基礎設施到以完全基於雲端計算的電子郵件傳送服務提供了堅實的基礎。

 

原文連結:

https://devops.com/7-principles-for-using-microservices-to-build-an-api-that-lasts/

 


更多技術分享請關注公眾號:JFrog 傑蛙 DevOps


2 11 日線上課堂:《容器持續交付流水線最佳實踐》

課堂收益:

1.基於 Jenkins Pipeline,搭建 Docker 容器自動化持續交付流水線。

2. 透過各階段自動化及手工測試的結果,形成多維度質量關卡,保障釋出包質量。

3. 開發測試映象和生產映象分庫管理,透過質量關卡的映象升級到生產庫,生產庫的映象許可權得到保障,避免映象被篡改。

4.為 Docker 映象構建進行持續的深度漏洞掃描,保證線上應用服務的安全。

5. 為應用依賴的資料庫等有狀態服務提供自動化地資料庫升級流程,規範自動化 CI/CD 流水線。

報名連結:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69954434/viewspace-2675158/,如需轉載,請註明出處,否則將追究法律責任。

相關文章