API設計:先思考再編碼
Web開發人員廣泛使用和討論的另一個概念是RESTFul Web API。它由Roy Fielding定義為一種架構風格,在客戶端和伺服器之間提供良好的通訊協議。它包含了一些約束:無狀態通訊,基礎技術(通常為HTTP)的使用和超媒體作為應用程式狀態的引擎的使用。換句話說,它提出了一些用於構建web API的模式。為了簡單起見,在這篇文章中將Web API簡稱為API。
一個JSON值一千字
讓我們看一個API響應的例子:
{
"data": [
{
"story": "Jonatas Baldin was writing a blog post.",
"created_time": "2017-15-01T00:02:57+0000",
"id": "624510964324764_1046909755418214"
},
]
}
這段JSON的資料是智慧手機從Facebook API響應中收集的Facebook狀態訊息的示例。很漂亮,對不對?
現在想象你是Facebook的工程師,負責這個API。有天您突然決定將id欄位名稱更改為message_id。嗯,這個小的變化可能破壞Facebook。真的。依賴於先前定義的結構的所有裝置現在都無法收集這個JSON響應,也就無法向使用者顯示任何內容。
好壞醜
一個壞的API設計遲早會造成各種麻煩:
1.沒有一致性:一旦API增長,端點往往只是為了滿足即時需求被建立。
2.難以擴充套件:在對端點進行故障排除時無法參考。
3.難學:消費使用資料和開發API會是一段陡峭的學習曲線。
4.效能問題:丟擲未進行規劃設計的API程式碼通常會長期產生效能瓶頸。
5.API往往是永恆的:第一次是讓它就能正確的最好機會。
API是您的應用程式與其使用者之間的合同。它不能突然改變,否則會導致那些已經呼叫它的客戶端發生混亂,API不應該在沒有預見性的情況下倉促建立。這就是需要設計的地方:建立一個規劃或約定,用於構建物件,系統或可衡量的人類互動。
第一件事:讓我們談談HTTP
在介紹API程式碼之前,讓我們先看一下超文字傳輸協議HTTP,顧名思義,它是用於在網路上傳輸資料。它有一組關於客戶端和伺服器如何交換資訊的規則。其主要組成部分有:
URL:您的資源在Web上的位置,您的端點的地址。一個示例是使用http://example.org/users列出您的使用者。
請求方法:客戶端希望在特定端點上執行的操作。GET 用於檢索資源,POST建立一個,PUT 和PATCH 來更新現有的資源,DELETE刪除東西。
頭部Header:包含有關客戶端或伺服器的資訊。例如:內容型別(格式)、方法、認證令牌和其他。
正文內容body:客戶端與伺服器之間傳送和接收的資料。JSON是事實上的標準。
狀態程式碼:一個三位數字,用於告知請求狀態。總而言之,2xx 狀態表示成功,4xx意味著客戶端錯誤,5xx意味著服務錯誤。
讓我們看一個HTTP請求/響應示例:
Client request: GET /users/1 HTTP/1.1 Host: www.example.org/users Server response: HTTP/1.1 200 OK Content-Type: application/json Date: Sun, 19 Feb 2017 00:43:51 GMT { "id": 1, "first_name": "Jonatas", "fast_name": "Baldin", "role": "Caker" } <p class="indent"> |
良好的API設計需要良好的規格
在設計API時,有一些規範可以幫助您。最常用的是使用純JSON的Swagger、使用YAML表示法的RAML和支援markdown語法的API藍圖Blueprint。我喜歡上了後者:即使它是鄰居新的酷孩子,它已經成熟足夠和能夠讓人愉快的工作。這裡會闡述為什麼。
從官方網站上獲得定義:
API藍圖(支援markdown語法)是簡單的,並且可以在API生命週期的訪問每個元素。它的語法簡潔而富有表現力。使用API 藍圖,您可以快速設計和建立API,或記錄和測試已部署的任務關鍵型API。
它是一個開放原始碼,專注於協作,易於學習和良好記錄的規範,由Apiary建立,其核心是設計第一,周圍有一些很棒的工具:從模擬伺服器生成器到全功能生命週期解決方案。
除了藍圖,還有MSON(Markdown語法物件符號),它以人類可讀的方式定義資料結構,不是手動編寫端點的主體資料,而是在可重用物件中表示它們。
以下是您需要了解的資訊:
API名稱,描述和後設資料:關於API和藍圖版本的一些描述。
資源組:相關資源組,比如Users。
資源:定義唯一資源,它的端點和操作。
引數:在端點中用於指定動態引數,如ID或查詢搜尋。
響應:內容型別,HTTP狀態程式碼和主體資料。
除此之外,蜜蜂是一個協作平臺,用於建立、呈現、測試和服務您的API。他們有一個免費的公共專案計劃,你可以直接用你的GitHub帳戶註冊,以建立自己的設計。
這裡是一個藍圖程式碼示例:
FORMAT: 1A HOST: http://cakes.ckl.io/ # Cakes API Cakes is an API used to store and consume information about the most loved Cakes here at Cheesecake Labs. Cakes是一個API,用於儲存和消費關於Cheesecake Labs最受歡迎的蛋糕的資訊。 # Group Cakes ## Cakes [/cakes/] ### List all Cakes [GET] + Response 200 (application/json) + Attributes (array[Cake]) # Data Structures ## Cake (object) + id: `1` (string, required) - The unique ID of a Cake. + name: `Cheesecake` (string, required) - The name of a Cake. + rating: `5/5` (string, optional) - The rating of a Cake. <p class="indent"> |
如果您訪問上面這個專案,您將看到一個漂亮的頁面。真棒是:自動為每個專案建立模擬伺服器是 - 見這裡,看到魔法嗎?不需要程式碼它也工作。任何有HTTP和Blueprint基本知識的人都可以建立一個模擬API,並從客戶那裡獲得反饋。
上面的例子很簡單,可以透過get獲得。您可以檢視藍圖教程和文件以深入瞭解其語法,並在此處閱讀規範。此外,這是一個開源專案 - 歡迎社群的任何貢獻。
恭喜!現在你掌握了設計API所需的知識。但在你開始啟動你的系統之前,這裡有一些小提示:
該做什麼和不該做什麼
這裡是簡單設計規則和最佳實踐:
1.將端點操作視為CRUD(L)操作
我們的/cakes/端點可能有建立,讀取,更新,刪除和列表操作。你可以使用HTTP動詞和URL來構造這些動作,例如:
列表:GET /cakes/
建立:POST /cakes/
閱讀:GET /cakes/1/
更新:PATCH /cakes/1/
刪除:DELETE /cakes/1/
2.正確使用HTTP方法
GET是獲得,POST是釋出。如果你只是想要一個蛋糕的列表不要使用POST。
3.HTTP是有方法的,使用它們!
POST /cakes/createCake
你不需要在URL中指定操作,我們已經知道POST建立一些東西,所以createCake不需要包含create字眼。
POST /cakes/
更清晰的URL,也會告訴我們可能其他方法將按這種方式使用,如GET /cakes。
4.單數還是複數!
GET /cakes應該返回一個蛋糕列表,所以GET /cake/1應該返回第一個蛋糕,對吧?很不幸的是,不行。即使它在我們的語言是有道理的,它只會用更多端點搞亂客戶端和開發人員。
5.搜尋,排序,限制?使用查詢引數!
此功能允許您指定一些過濾列表端點,這裡是一個例子:
GET /cakes/?name=apple
如果實現,應該所有名稱是蘋果的蛋糕。
GET /cakes/?name=apple&rating=4
您也可以使用連線引數&,搜尋apple和評級為4的蛋糕。
6.使用4xx返回錯誤。
每個人都憎恨HTTP響應狀態程式碼是2xx,卻返回一個錯誤的訊息!使用正確的程式碼:
401:未經授權的訪問,授權過程未正確完成。
403:禁止訪問,客戶端被授權,但是沒有訪問資源。
404:著名未找到,表示資源不可用。
7.請清楚地描述您的錯誤
當發生問題失敗時,通知客戶端發生了什麼以及如何恢復。這裡有一個很好的方法:
{ "error": { "type": "Authentication Error", "details": "Authentication could not be established with the given username and password", } } <p class="indent"> |
大家都明白。
8.資源淚水物件類
API端點將使用資源表示進行響應。將這些資源當作物件類,然後在現實世界中代表事物。
相信我,使用設計第一的哲學將帶給你更好的睡眠。這裡有一些好的API優點:
與您的客戶交談:瞭解他們需要什麼,而不是他們想要什麼。沒有客戶端的API只是一個壞的API。
易於使用:端點,資源和輸出資料應儘可能遵循相同的結構。
難以誤用:如果發出了錯誤的請求,返回錯誤並提供資訊。
簡單是比複雜更好:簡單的事情在每個方面都很容易。
在實現它之前使用你的API:建立一個模擬伺服器來獲得最終結果並演示。如果可以,與您未來的客戶談話並詢問他們的意見。
有彈性:當發生崩潰時,告知為什麼以及如何處理這種情況。
測試一切。為每個端點,方法,引數,輸入和輸出資料編寫測試。
你的API是一種新的小語言,你必須教會其他人使用它。
相關文章
- Swift API 設計思考題SwiftAPI
- 別再設計易碎的Web API!WebAPI
- 錯誤碼設計思考
- 程式設計師真的“編碼太多沒時間思考”了嗎程式設計師
- 我的程式設計認知:多思考、多編碼、多測試程式設計
- 程式設計師嘛,先做個好架構師再說程式設計師架構
- 阿里研究員谷樸:API 設計最佳實踐的思考阿里API
- EventBus/EventQueue 再思考
- 程式設計:思考?打字?思考!打字!程式設計
- android 關於先登入成功後再進入目標介面的思考Android
- 請先思考 再回答
- 先分析,再脫殼(一)
- ETL設計與思考
- Apache Kafka設計思考ApacheKafka
- Just-API:無需編碼測試APIAPI
- 程式設計:思考或打字,思考和打字程式設計
- 前端設計與編碼規範前端
- Filter 設計模式編碼實踐Filter設計模式
- 程式設計師 vs 編碼員程式設計師
- [譯]編碼,編碼,編碼!提高程式設計技能的唯一途徑程式設計
- 再談Net Framework中的編解碼Framework
- 登錄檔單中密碼遮蔽的再設計密碼
- 少編碼多思考:程式碼越多 問題越多
- 編寫高質量程式碼的思考
- Rxjava原始碼思路分析與程式設計師的思考RxJava原始碼程式設計師
- API介面設計API
- 上位機程式設計編碼規範程式設計
- 雲端計算再思考:亞馬遜 re:Invent帶來哪些啟示?亞馬遜
- 程式設計入門之字元編碼與亂碼程式設計字元
- 設計流暢的API(Fluent API)API
- 是先做資料庫設計還是先建模資料庫
- 別再設計易碎的WebAPIWebAPI
- 線性思考、設計思考和系統思考三者權衡
- 【程式設計素質】Java編碼約定程式設計Java
- Web設計師需要編碼知識嗎?Web
- 物件導向的編碼設計原則物件
- restful api設計指南RESTAPI
- 理解RESTful Api設計RESTAPI