15個與語言無關的REST API設計技巧 - bluethl
在這篇文章中,我正在盡我最大的努力壓縮我所知道的關於什麼是好的 API 的一切。您的消費者會喜歡使用的 API。所有提示都與語言無關,因此它們適用於任何框架或技術。
1. 保持一致
- 對欄位、資源和引數使用相同的大小寫(我更喜歡snake_case)
- 使用複數或單數資源名稱(我更喜歡複數)
- /users/{id},/orders/{id}或/user/{id},/order/{id}
- 對所有端點使用相同的身份驗證和授權方法
- 在 API 中使用相同的 HTTP 標頭
- 例如Api-Key用於傳遞 API 金鑰
- 根據響應型別使用相同的 HTTP 狀態程式碼
- 例如404,當找不到資源時
- 對相同型別的操作使用相同的 HTTP 方法
- 例如DELETE刪除資源時
2. 使用ISO 8601 UTC 日期
在處理日期和時間時,API 應始終返回 ISO 8601 格式的字串。在特定時區顯示日期通常是客戶端應用程式關心的問題。
{ "published_at": "2022-03-03T21:59:08Z" } |
3. 對公共端點進行例外處理
預設情況下,每個端點都應該需要授權。大多數端點都需要呼叫經過身份驗證的使用者,因此將其設為預設值是有意義的。如果需要公開呼叫端點,請顯式設定此端點以允許未經授權的請求。
4.提供健康檢查端點
GET /health提供一個確定服務是否健康的端點(例如)。其他應用程式(例如負載均衡器)可以呼叫此端點以在服務中斷時採取行動。
5. 版本化 API
確保對 API 進行版本控制並在每個請求中傳遞版本,這樣消費者就不會受到對另一個版本的任何更改的影響。API 版本可以使用 HTTP 標頭或查詢/路徑引數傳遞。即使是 API 的第一個版本(1.0)也應該明確地進行版本控制。
一些例子:
- https://api.averagecompany.com/v1/health
- https://api.averagecompany.com/health?api_version=1.0
6.接受API金鑰認證
如果 API 需要由第三方呼叫,則允許透過 API 金鑰進行身份驗證是有意義的。API 金鑰應使用自定義 HTTP 標頭(例如Api-Key)傳遞。它們應該有一個到期日期,並且必須可以撤銷活動金鑰,以便在它們受到損害時可以使它們失效。避免將 API 金鑰簽入原始碼控制(改用環境變數)。
7. 使用合理的 HTTP 狀態碼
使用傳統的 HTTP 狀態程式碼來指示請求的成功或失敗。不要使用太多,並在整個 API 中為相同的結果使用相同的狀態程式碼。一些例子:
- 200取得普遍成功
- 201為成功創作
- 400對於來自客戶端的錯誤請求
- 401對於未經授權的請求
- 403缺少許可權
- 404對於缺少的資源
- 429對於太多的請求
- 5xx對於內部錯誤(應不惜一切代價避免這些錯誤)
8.使用合理的HTTP方法
HTTP 方法有很多,但最重要的是:
- POST用於建立資源
- POST /users
- GET用於閱讀資源(單個資源和集合)
- GET /users
- GET /users/{id}
- PATCH用於對資源應用部分更新
- PATCH /users/{id}
- PUT用於對資源應用完整更新(替換當前資源)
- PUT /users/{id}
- DELETE用於刪除資源
- DELETE /users/{id}
9.使用不言自明、簡單的名字
大多數端點都是面向資源的,應該這樣命名。不要新增可以從其他地方推斷出的不必要的資訊。這也適用於欄位名稱。
好:
- GET /users=> 檢索使用者
- DELETE /users/{id}=> 刪除使用者
- POST /users/{id}/notifications=> 為特定使用者建立通知
- user.first_name
- order.number
壞:
- GET /getUser
- POST /updateUser
- POST /notification/user
- order.ordernumber
- user.firstName
10. 使用標準化的錯誤響應
除了使用指示請求結果(成功或錯誤)的 HTTP 狀態程式碼外,在返回錯誤時,始終使用標準化的錯誤響應,其中包含有關問題的更詳細資訊。消費者總是可以期待相同的結構並採取相應的行動。
// Request => GET /users/4TL011ax // Response <= 404 Not Found { "code": "user/not_found", "message": "A user with the ID 4TL011ax could not be found." } // Request => POST /users { "name": "John Doe" } // Response <= 400 Bad Request { "code": "user/email_required", "message": "The parameter [email] is required." } |
11. 返回建立的資源POST
POST在使用請求建立資源後返回建立的資源是個好主意。這一點很重要,因為返回的建立資源將反映底層資料來源的當前狀態,並將包含更新的資訊(例如生成的 ID)。
// Request: POST /users { "email": "jdoe@averagecompany.com", "name": "John Doe" } // Response { "id": "T9hoBuuTL4", "email": "jdoe@averagecompany.com", "name": "John Doe" } |
12. PATCH好於PUT
如前所述,PATCH請求應該對資源應用部分更新,而PUT完全替換現有資源。
而圍繞 PATCH 請求設計更新通常是個好主意,因為:
- 當使用PUT只更新資源的一部分欄位時,仍然需要傳遞整個資源,這使得它更加網路密集且容易出錯
- 允許任何欄位不受任何限制地更新也是相當危險的
- 根據我的經驗,在實踐中幾乎不存在任何對資源進行完整更新有意義的用例
- 想象一個order資源有一個id和一個state
- 允許消費者更新state一個order
- 狀態更改更有可能由另一個端點(例如/orders/{id}/fulfill)觸發
13. 儘可能具體
如上一節所述,在設計端點、命名欄位以及決定接受哪些請求和響應時,儘可能具體是一個好主意。如果一個PATCH請求只接受兩個欄位 (name和description),則不存在錯誤使用它和損壞資料的危險。
14.使用分頁
對所有返回資源集合並使用相同響應結構的請求進行分頁。使用page_numberand page_size(或類似的)來控制要檢索的塊。
// Request => GET /users?page_number=1&page_size=15 // Response <= 200 OK { "page_number": 1, "page_size": 15, "count": 378, "data": [ // resources ], "total_pages": 26, "has_previous_page": true, "has_next_page": true } |
15.允許擴充套件資源
允許消費者使用名為expand(或類似的)查詢引數載入相關資料。這對於避免往返和一次性載入特定操作所需的所有資料特別有用。
// Request => GET /users/T9hoBuuTL4?expand=orders&expand=orders.items // Response <= 200 OK { "id": "T9hoBuuTL4", "email": "jdoe@averagecompany.com", "name": "John Doe", "orders": [ { "id": "Hy3SSXU1PF", "items": [ { "name": "API course" }, { "name": "iPhone 13" } ] }, { "id": "bx1zKmJLI6", "items": [ { "name": "SaaS subscription" } ] } ] } |
相關文章
- 13 個設計 REST API 的最佳實踐RESTAPI
- Django 中 REST API 的設計DjangoRESTAPI
- 【語言】Java 日期 API 的使用技巧JavaAPI
- Swift程式設計的15個技巧Swift程式設計
- Coco學程式設計--《設計模式》,語言無關的好書 (轉)程式設計設計模式
- rest-api設計風格RESTAPI
- 函數語言程式設計中的常用技巧函數程式設計
- 一個關於pynoi遊戲的C語言程式設計遊戲C語言程式設計
- 如何提高函數語言程式設計技巧函數程式設計
- 15個提高程式設計技巧的JavaScript工具程式設計JavaScript
- C語言高效程式設計的的四招技巧[轉]C語言程式設計
- Django REST framework API 指南(15):限流DjangoRESTFrameworkAPI
- 谷歌大牛的 C 語言程式設計建議和技巧谷歌程式設計
- Airbnb的設計之道:明晰與優雅的設計語言AI
- Go 語言的 10 個實用技巧Go
- 一個C語言宣告解析器的設計與實現C語言
- 符合語言習慣的 Python 優雅程式設計技巧Python程式設計
- 函數語言程式設計的優與劣函數程式設計
- 語言學與面對物件的設計 (轉)物件
- iOS 與 函數語言程式設計iOS函數程式設計
- Reactive設計語言與正規化React
- Battleship程式設計語言與技術BAT程式設計
- 30秒無需編碼完成一個REST API服務RESTAPI
- 函數語言程式設計的幾個概念函數程式設計
- 關於函數語言程式設計的思考(1)函數程式設計
- 關於函數語言程式設計的思考(2)函數程式設計
- 關於C語言的圖形程式設計薦C語言程式設計
- 改變遊戲規則的 API 設計審查的5個技巧遊戲API
- Python學習中:最感到驚奇35個語言特徵和程式設計技巧Python特徵程式設計
- JavaScript 函數語言程式設計技巧 - 反柯里化JavaScript函數程式設計
- 前端程式設計師應該知道的 15 個 jQuery 小技巧前端程式設計師jQuery
- C++語言的15個晦澀特性C++
- 學寫PEP,參與Python語言的設計Python
- 很酷的 C 語言技巧
- 5個REST API安全準則RESTAPI
- 使用C語言程式設計的7個步驟C語言程式設計
- 一個 Java 程式設計師眼中的 Go 語言Java程式設計師Go
- 一個Go語言程式設計的好選題Go程式設計