一帝簇、什么是API規(guī)范
二、OpenAPI規(guī)范
2.1 協(xié)議
2.2 版本(Version)
2.3 Schema
2.4 以資源為中心的 URL 設(shè)計
2.5 正確使用 HTTP Method
2.5 狀態(tài)碼 (Status Code)
2.7 錯誤處理(Error Handling)
2.8 命名規(guī)則
2.9 認證和授權(quán)(Authentication & Authorization)
2.10 限流(RateLimit)
2.11 編寫優(yōu)秀的文檔
一忆嗜、什么是API規(guī)范
API 是模塊或者子系統(tǒng)之間交互的接口定義己儒。好的系統(tǒng)架構(gòu)離不開好的 API 設(shè)計,而一個設(shè)計不夠完善的 API 則注定會導致系統(tǒng)的后續(xù)發(fā)展和維護非常困難捆毫。在關(guān)鍵環(huán)節(jié)制定明確的API規(guī)范有助于 Service 對內(nèi)提高產(chǎn)品間互通的效率,對外提供一致的使用體驗冲甘,也有助于更好地被集成绩卤。
對于API規(guī)范,比較知名的是 OpenAPI Specfication 和 Google API Design Guide 江醇。前者針對 RESTful API 設(shè)計在細節(jié)層面給出了非常具體的規(guī)定濒憋,已經(jīng)成為 RESTful API 設(shè)計領(lǐng)域的事實標準,而后者則主要從云廠商的角度提出許多最佳實踐性質(zhì)的規(guī)范與建議陶夜,這些原則不僅僅適用于 RESTful API凛驮,也適合其他類型API設(shè)計。
雖然RESTful設(shè)計風格曝光率很高条辟,但并不是所有云服務(wù)商都選擇了完全遵循RESTful黔夭,例如AWS和 阿里云 RPC 風格反而占了大多數(shù),Google和Azure則RESTful居多羽嫡。
RESTful API的優(yōu)勢是HTTP具備更好的易用性本姥,讓異構(gòu)系統(tǒng)更容易集成,且開發(fā)執(zhí)行效率比較高杭棵,面向資源要求也比較高婚惫。而RPC API可以使用更廣泛的框架和方案,技術(shù)層面更底層也更為靈活,設(shè)計起來相對簡單先舷,掌握起來有一定門檻艰管,架構(gòu)上更加復雜。RESTful 與 RPC 模式對比如下:
RESTful API | RPC API | |
---|---|---|
是否有統(tǒng)一規(guī)范 | HTTP | 無 |
面向資源 | 是 | 不確定 |
性能 | 中 | 高 |
通用性 | 高 | 弱 |
復雜度 | 中 | 高 |
如果強制統(tǒng)一風格蒋川,有些適合 RESTful 風格的服務(wù)非要使用RPC的話蛙婴,看起來就會比較丑陋,如果只是一個過程化的服務(wù)調(diào)用尔破,往 RESTful 資源化設(shè)計方向去靠會比較困難街图。但如果不強制使用統(tǒng)一風格,會造成針對API的體系化支持會更加復雜懒构,例如為兼容兩種風格SDK的自動化支持需要兩套代碼餐济。
選擇API風格時要考慮幾個問題:
- 選擇支持哪種風格,才能更好地體現(xiàn)業(yè)務(wù)特性胆剧,讓客戶操作起來更加方便絮姆;
- 設(shè)計API時能否面向資源設(shè)計,相應的工程人員是否具備做這種設(shè)計的能力秩霍;
- 針對這種風格工具鏈的支持是否到位篙悯,投入產(chǎn)出比如何;
- 業(yè)界流行的趨勢如何铃绒,是否需要考慮與其他系統(tǒng)體系的互操作鸽照。
用戶使用API來訪問 Service,本質(zhì)上是想通過對某種資源執(zhí)行特定的操作來完成一個業(yè)務(wù)動作颠悬。對于資源有兩個關(guān)鍵點:一是要有統(tǒng)一的資源模型矮燎;二是要明確資源關(guān)系。統(tǒng)一的資源模型對 Service 的幫助是巨大的:
- 它可以使API具有更清晰的結(jié)構(gòu)赔癌,幫助用戶理解诞外;
- 它可以幫助對比API與后臺實體關(guān)系模型,更容易提供更完整的API服務(wù)灾票;
- 它可以使產(chǎn)品協(xié)作更加順暢峡谊,對資源的操作也更加規(guī)范化;
- 它可以使云服務(wù)底層平臺實現(xiàn)起來更統(tǒng)一刊苍、更方便既们;
- 它可以使圍繞API的生態(tài)集成起來更加簡單、高效班缰。
確定了設(shè)計模式和資源模型后贤壁,就需要考慮 API的設(shè)計細節(jié)了,諸如API名稱埠忘、參數(shù)名脾拆、屬性名稱馒索、數(shù)據(jù)格式、錯誤碼之類的信息名船。除此之外绰上,還要考慮以下一些問題:
- 在API命名的時候,遵循什么樣的范式來確保大體風格相似渠驼?動詞蜈块、名詞、介詞如何組合才能保持API風格看起來比較統(tǒng)一迷扇,降低理解成本百揭?
- 對于類似的操作,有沒有使用規(guī)范蜓席?有哪些公共的標準詞匯使得同類型的操作可以比較容易理解器一,避免使用晦澀奇怪的詞匯(例如讀操作,Read/Query/Describe/List/Get中都在什么場合使用什么動詞)厨内?
- 被廣泛使用的參數(shù)如何盡可能保持一致祈秕,避免不同產(chǎn)品的表達混亂的情況(例如分頁參數(shù)用PageNumber還是PageNum)嗅蔬?
- 對于常用的場景胆萧,例如冪等彤避、分頁怎燥、異步API的設(shè)計有沒有統(tǒng)一的規(guī)范,避免使用體驗不一致征字?
- 錯誤碼應該怎么設(shè)計藏澳?公共錯誤碼怎么統(tǒng)一街州,業(yè)務(wù)錯誤碼怎么表達?
上述問題都是實際研發(fā)過程中要注意的面徽,要全部羅列的話遠不止這些。API的用詞描述是 Service 展現(xiàn)給外部用戶的第一印象碰酝,絕非隨意寫就送爸。對人員有一定規(guī)模铛嘱,內(nèi)部有多條產(chǎn)品線的組織來說暖释,如何協(xié)調(diào)組織的各個部分對外具有統(tǒng)一的體驗是個很大挑戰(zhàn)。
Service 在管理API時應該考慮一些具體的規(guī)范墨吓,對命名規(guī)則球匕、標準詞匯、最佳實踐模式帖烘、錯誤碼等信息都有明確的規(guī)定亮曹,同時用系統(tǒng)化、平臺化的手段來管理API秘症,確保不走偏照卦。設(shè)計風格不是云服務(wù)API設(shè)計中致命的問題,但是它關(guān)乎云服務(wù)外表形象乡摹,不可不察役耕。
API是后端服務(wù)的外部表達,是服務(wù)就有可能出現(xiàn)問題趟卸,無論這個問題是可預期的還是不可預期的蹄葱。如果只考慮功能本身功能特性,而忽視對異常情況的設(shè)計锄列,當問題出現(xiàn)的時候業(yè)務(wù)本身可能無法感知造成服務(wù)異常图云,更重要的是站在客戶角度去看,不能有效獲取錯誤原因是非常痛苦的邻邮,很多時候只能束手無策竣况,降低云服務(wù)提供商的整體口碑,甚至損害營收筒严。
二丹泉、 OpenAPI規(guī)范
本規(guī)范基于 RESTful 風格的架構(gòu)設(shè)計準則,廣泛參考 GitHub鸭蛙、Azure摹恨、Google API Design Guide、騰訊云娶视、阿里云等公開資料晒哄,兼顧現(xiàn)有實際情況和未來發(fā)展做一個概括性記錄總結(jié)。
2.1 協(xié)議
API 與用戶的通信協(xié)議肪获,總是使用 HTTPS 協(xié)議寝凌。這個和 RESTful API 本身沒有很大的關(guān)系,但是對于增加網(wǎng)站的安全是非常重要的孝赫。特別如果你提供的是公開 API较木,用戶的信息泄露或者被攻擊會嚴重影響網(wǎng)站的信譽。
2.2 版本(Version)
關(guān)于版本的設(shè)計有3種形式:
- 將 API 的版本號放入 URL 中青柄,如:
http://api.example.com/v1
伐债,這樣方便和直觀预侯; - 將版本號記錄在 url query中,如:
http://api.example.com?param1=val&version=1.0
中的 version 參數(shù)泳赋。 - 將版本號放在 HTTP 頭信息中雌桑,基于的準則是:不同的版本,可以理解成同一種資源的不同形式祖今,所以應該采用同一個URL校坑。如:
Accept: application/json; version=1.0
,可以參考Github API Design 和 Versioning REST Services 千诬;
根據(jù)現(xiàn)有的實際情況耍目,如果是為了兼容已存在的服務(wù)接口,可以采用對應的形式徐绑。如果是新構(gòu)建的體系結(jié)構(gòu)邪驮,建議采用第三種。
2.3 Schema
URI的格式定義如下:URI = scheme "://" authority "/" path \[ "?" query \] \[ "#" fragment \]
URL 是 URI 的一個子集(一種具體實現(xiàn))傲茄,對于 REST API 來說一個資源一般對應一個唯一的 URI(URL)毅访。在 URL 的設(shè)計中,我們會遵循一些規(guī)則盘榨,使接口看起透明易讀喻粹,方便使用者調(diào)用。
"/"分隔符一般用來對資源層級的劃分草巡。對于 RESTful API 來說守呜,"/"只是一個分隔符,并無其他含義山憨。為了避免混淆查乒,"/"不應該出現(xiàn)在URL的末尾。
URL 中盡量使用連字符"-"代替下劃線"_"的使用郁竟。 連字符"-"一般用來分割 URL 中出現(xiàn)的字符串(單詞)玛迄,來提高 URL 的可讀性,例如:http://api.example.restapi.org/blogs/mark-masse/entries/this-is-my-first-post
棚亩。使用下劃線""來分割字符串(單詞)可能會和鏈接的樣式?jīng)_突重疊憔晒,而影響閱讀性。但實際上蔑舞,"-"和""對URL 中字符串的分割語意上還是有些差異的:"-"分割的字符串(單詞)一般各自都具有獨立的含義,可參見上面的例子嘹屯。而"_"一般用于對一個整體含義的字符串做了層級的分割攻询,方便閱讀,例如你想在 URL 中體現(xiàn)一個 IP 地址的信息:210_110_25_88 . (歡迎關(guān)注:朱小廝的博客)
URL應該統(tǒng)一使用小寫字母 州弟。
URL中不要包含文件(腳本)的擴展名 钧栖。例如 .json
之內(nèi)的就不要出現(xiàn)了低零,對于接口來說沒有任何實際的意義。如果是想對返回的數(shù)據(jù)內(nèi)容格式標示的話拯杠,通過 HTTP Header 中的 Content-Type 字段更好一些掏婶。
對于響應返回的格式,JSON 因為它的可讀性潭陪、緊湊性以及多種語言支持等優(yōu)點雄妥,成為了 HTTP API 最常用的返回格式。因此依溯,最好采用 JSON 作為返回內(nèi)容的格式老厌。如果用戶需要其他格式,比如 xml
黎炉,應該在請求頭部 Accept
中指定枝秤。對于不支持的格式,服務(wù)端需要返回正確的 status code
慷嗜,并給出詳細的說明淀弹。
JSON中的所有字段都應該用小寫的蛇形命名形式,而不是采用駝峰命名庆械。
2.4 以資源為中心的 URL 設(shè)計
資源是 Restful API
的核心元素薇溃,所有的操作都是針對特定資源進行的。而資源就是 URL
(Uniform Resoure Locator)表示的干奢,所以簡潔痊焊、清晰、結(jié)構(gòu)化的 URL 設(shè)計是至關(guān)重要的忿峻。Github 可以說是這方面的典范薄啥,下面我們就拿 repository
來說明:
/users/:username/repos
/users/:org/repos
/repos/:owner/:repo
/repos/:owner/:repo/tags
/repos/:owner/:repo/branches/:branch
我們可以看到幾個特性:
- 資源分為單個文檔和集合,盡量使用復數(shù)來表示資源逛尚,單個資源通過添加 id 或者 name 等來表示
- 一個資源可以有多個不同的 URL
- 資源可以嵌套垄惧,通過類似目錄路徑的方式來表示,以體現(xiàn)它們之間的關(guān)系
最常見的一種設(shè)計錯誤绰寞,就是URL包含動詞到逊。 因為"資源"表示一種實體,所以應該是名詞滤钱,URL 不應該有動詞觉壶,動詞應該放在 HTTP Method (參考下一條)中。舉例來說件缸,某個 URL 是 /users/show/1
铜靶,其中 show
是動詞,這個 URL 就設(shè)計錯了他炊,正確的寫法應該是 /users/1
争剿,然后用 HTTP GET 方法表示 show已艰。
如果某些動作是HTTP 動詞表示不了的,你可以把動作看成是一種資源蚕苇。比如網(wǎng)上匯款哩掺,從賬戶1向賬戶2匯款500元,錯誤的 URL 是:
POST /accounts/1/transfer/500/to/2
正確的寫法是把動詞 transfer 改成transaction涩笤,資源不能是動詞嚼吞,但是可以是一種服務(wù):
POST /transactoin HTTP/1.1
HOST: 127.0.0.1
from=1&to=2&amount=500
2.5 正確使用 HTTP Method
有了資源的 URI 設(shè)計,所有針對資源的操作都是使用 HTTP 方法指定的辆它。比較常用的 HTTP/1.1 動詞有下面5個:
- GET:從服務(wù)器取出資源(一項或多項)誊薄。
- POST:在服務(wù)器新建一個資源。
- PUT:在服務(wù)器更新資源(客戶端提供改變后的完整資源)锰茉。
- PATCH:在服務(wù)器更新資源(更新資源的部分屬性)呢蔫。
- DELETE:從服務(wù)器刪除資源。
還有4個不常用的 HTTP/1.1 動詞:
- HEAD:只獲取某個資源的頭部信息飒筑。比如只想了解某個文件的大小片吊,某個資源的修改日期等
- OPTIONS:獲取信息,關(guān)于資源的哪些屬性是客戶端可以改變的协屡。
- TRACE:追蹤路徑俏脊。不建議使用。
- CONNECT:要求用隧道協(xié)議連接代理肤晓。不建議使用爷贫。
舉例:
GET /repos/:owner/:repo/issues
GET /repos/:owner/:repo/issues/:number
POST /repos/:owner/:repo/issues
PATCH /repos/:owner/:repo/issues/:number
DELETE /repos/:owner/:repo
這里順帶探討一下,HTTP 協(xié)議涉及到的一種重要性質(zhì):冪等性(Idempotence)补憾。在 HTTP/1.1 規(guī)范中冪等性的定義是:
Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.
從定義上看漫萄,HTTP 方法的冪等性是指一次和多次請求某一個資源應該具有同樣的副作用。冪等性屬于語義范疇盈匾,正如編譯器只能幫助檢查語法錯誤一樣腾务,HTTP 規(guī)范也沒有辦法通過消息格式等語法手段來定義它,這可能是它不太受到重視的原因之一削饵。但實際上岩瘦,冪等性是分布式系統(tǒng)設(shè)計中十分重要的概念,而 HTTP 的分布式本質(zhì)也決定了它在 HTTP 中具有重要地位窿撬。
安全方法是指不修改資源的 HTTP 方法启昧。譬如,當使用 GET 或者 HEAD 作為資源 URL劈伴,都必須不去改變資源箫津。然而,這并不全準確。意思是:它不改變資源的表示形式苏遥。對于安全方法,它仍然可能改變服務(wù)器上的內(nèi)容或資源赡模,但這必須不導致不同的表現(xiàn)形式田炭。
HTTP Method | 冪等 | 安全 | |
---|---|---|---|
1 | OPTIONS | yes | yes |
2 | GET | yes | yes |
3 | HEAD | yes | yes |
4 | PUT | yes | no |
5 | POST | no | no |
6 | DELETE | yes | no |
7 | PATCH | no | no |
實際上接口的冪等或者安全與否取決于接口的實現(xiàn),只是 HTTP Method 語義上我們約定俗成地認為實現(xiàn)的過程會參照上表所示漓柑。對于冪等的接口教硫,客戶端就可以放心地多次調(diào)用,網(wǎng)關(guān)層面也可以重試辆布。
2.6 狀態(tài)碼 (Status Code)
HTTP 應答中瞬矩,需要帶一個很重要的字段:status code
。它說明了請求的大致情況锋玲,是否正常完成景用、需要進一步處理、出現(xiàn)了什么錯誤惭蹂,對于客戶端非常重要伞插。狀態(tài)碼都是三位的整數(shù),大概分成了幾個區(qū)間:
-
2XX
:請求正常處理并返回 -
3XX
:重定向盾碗,請求的資源位置發(fā)生變化 -
4XX
:客戶端發(fā)送的請求有錯誤 -
5XX
:服務(wù)器端錯誤
在 HTTP API 設(shè)計中媚污,經(jīng)常用到的狀態(tài)碼以及它們的意義如下表:
Status Code | 語義 | 說明 |
---|---|---|
200 | OK | 請求已成功 |
201 | Created | 請求已完成,并導致了一個或者多個資源被創(chuàng)建廷雅,最常用在 POST 創(chuàng)建資源的時候 |
202 | Accepted | 請求已經(jīng)接收并開始處理耗美,但是處理還沒有完成。一般用在異步處理的情況航缀,響應 body 中應該告訴客戶端去哪里查看任務(wù)的狀態(tài) |
204 | No Content | 請求已經(jīng)處理完成商架,但是沒有信息要返回,經(jīng)常用在 PUT 更新資源的時候(客戶端提供資源的所有屬性谬盐,因此不需要服務(wù)端返回)甸私。如果有重要的 metadata,可以放到頭部返回 |
301 | Moved Permanently | 請求的資源已經(jīng)永久性地移動到另外一個地方飞傀,后續(xù)所有的請求都應該直接訪問新地址皇型。服務(wù)端會把新地址寫在 Location 頭部字段,方便客戶端使用砸烦。允許客戶端把 POST 請求修改為 GET弃鸦。 |
302 | Moved Temporarily | 臨時重定向 |
304 | Not Modified | 請求的資源和之前的版本一樣,沒有發(fā)生改變幢痘。用來緩存資源唬格,和條件性請求(conditional request)一起出現(xiàn) |
307 | Temporary Redirect | 目標資源暫時性地移動到新的地址,客戶端需要去新地址進行操作,但是 不能 修改請求的方法购岗。 |
308 | Permanent Redirect | 和 301 類似汰聋,除了客戶端 不能 修改原請求的方法 |
400 | Bad Request | 1.語義有誤,當前請求無法被服務(wù)器理解; 2. 請求參數(shù)有誤喊积。 |
401 | Unauthorized | 當前請求需要身份驗證烹困。 |
403 | Forbidden | 服務(wù)器已經(jīng)理解請求,但是拒絕執(zhí)行它乾吻。與401響應不同的是髓梅,身份驗證并不能提供任何幫助,而且這個請求也不應該被重復提交绎签。如果這不是一個 HEAD 請求枯饿,而且服務(wù)器希望能夠講清楚為何請求不能被執(zhí)行,那么就應該在實體內(nèi)描述拒絕的原因诡必。當然服務(wù)器也可以返回一個404響應奢方,假如它不希望讓客戶端獲得任何信息。 |
404 | Not Found | 請求失敗擒权,請求所希望得到的資源未被在服務(wù)器上發(fā)現(xiàn)袱巨。 |
405 | Method Not Allowed | 請求行中指定的請求方法不能被用于請求相應的資源。該響應必須返回一個Allow 頭信息用以表示出當前資源能夠接受的請求方法的列表碳抄。鑒于 PUT愉老,DELETE 方法會對服務(wù)器上的資源進行寫操作,因而絕大部分的網(wǎng)頁服務(wù)器都不支持或者在默認配置下不允許上述請求方法剖效,對于此類請求均會返回405錯誤嫉入。 |
406 | Not Acceptable | 請求的資源的內(nèi)容特性無法滿足請求頭中的條件,因而無法生成響應實體璧尸。 |
409 | Conflict | 由于和被請求的資源的當前狀態(tài)之間存在沖突咒林,請求無法完成。 |
429 | Too Many Requests | 資源配額不足或達到速率限制爷光。 |
499 | Client Closed Request | 請求被客戶端取消垫竞。 |
500 | Internal Server Error | 服務(wù)器內(nèi)部錯誤 |
501 | Not Implemented | 服務(wù)器不支持當前請求所需要的某個功能。當服務(wù)器無法識別請求的方法蛀序,并且無法支持其對任何資源的請求欢瞪。 |
502 | Bad Gateway | 作為網(wǎng)關(guān)或者代理工作的服務(wù)器嘗試執(zhí)行請求時,從上游服務(wù)器接收到無效的響應徐裸。 |
503 | Service Unavailable | 由于臨時的服務(wù)器維護或者過載遣鼓,服務(wù)器當前無法處理請求。這個狀況是臨時的重贺,并且將在一段時間以后恢復骑祟。 |
504 | Gateway Timeout | 作為網(wǎng)關(guān)或者代理工作的服務(wù)器嘗試執(zhí)行請求時回懦,未能及時從上游服務(wù)器(URI標識出的服務(wù)器,例如HTTP次企、FTP怯晕、LDAP)或者輔助服務(wù)器(例如DNS)收到響應。 |
505 | HTTP Version Not Supported | 服務(wù)器不支持抒巢,或者拒絕支持在請求中使用的 HTTP 版本贫贝。 |
上面這些狀態(tài)碼覆蓋了 API 設(shè)計中大部分的情況,如果對某個狀態(tài)碼不清楚或者希望查看更完整的列表蛉谜,可以參考 HTTP Status Code 、維基百科-狀態(tài)碼 或者 RFC7231 Response Status Codes 的內(nèi)容崇堵。
2.7錯誤處理(Error Handling)
如果出錯型诚,應該在 response body 中通過 message
給出明確的錯誤信息(一般來說,返回的信息中將 message 作為鍵名鸳劳,出錯詳情作為鍵值即可)狰贯。比如客戶端發(fā)送的請求有錯誤,一般會返回 4XX Bad Request
結(jié)果赏廓。這個結(jié)果很模糊涵紊,給出錯誤 message
的話,能更好地讓客戶端知道具體哪里有問題幔摸,進行快速修改摸柄。
{
"message":"錯誤詳情"
}
錯誤詳情應該可以幫助用戶輕松快捷地理解和解決API 錯誤。通常既忆,在編寫錯誤詳情時請考慮以下準則:
- 不要假設(shè)用戶是您 API 的專家用戶驱负。用戶可能是客戶端開發(fā)人員、操作人員患雇、IT 人員或應用的最終用戶跃脊。
- 不要假設(shè)用戶了解有關(guān)服務(wù)實現(xiàn)的任何信息,或者熟悉錯誤的上下文(例如日志分析)苛吱。
- 如果可能酪术,應構(gòu)建錯誤詳情,以便技術(shù)用戶(但不一定是 API 開發(fā)人員)可以響應錯誤并改正翠储。
- 確保錯誤詳情內(nèi)容簡潔绘雁。如果需要,請?zhí)峁┮粋€鏈接彰亥,便于有疑問的讀者提問咧七、提供反饋或詳細了解錯誤詳情中不方便說明的信息。此外任斋,可使用詳細信息字段來提供更多信息继阻。
2.8命名規(guī)則
為了能夠長時間在眾多 API 中為開發(fā)者提供一致的體驗耻涛,API 使用的所有名稱都應該具有以下特點:
- 簡單
- 直觀
- 一致
這包括接口、資源瘟檩、集合抹缕、方法和消息的名稱。
由于很多開發(fā)者不是以英語為母語墨辛,所以這些命名慣例的目標之一是確保大多數(shù)開發(fā)者可以輕松理解 API卓研。對于方法和資源,我們鼓勵使用簡單睹簇、直觀和少量的詞匯來命名奏赘。
- API 名稱 應該 使用正確的美式英語。例如太惠,使用美式英語的 license磨淌、color,而非英式英語的 licence凿渊、colour梁只。
- 為了簡化命名, 可以 使用已被廣泛接受的簡寫形式或縮寫埃脏。例如搪锣,API 優(yōu)于 Application Programming Interface。
- 盡量使用直觀彩掐、熟悉的術(shù)語构舟。例如,如果描述移除(和銷毀)一個資源佩谷,則刪除優(yōu)于擦除旁壮。
- 使用相同的名稱或術(shù)語命名同樣的概念,包括跨 API 共享的概念谐檀。
- 避免名稱過載抡谐。使用不同的名稱命名不同的概念。
- 避免在 API 的上下文以及更大的 API 生態(tài)系統(tǒng)中使用含糊不清且過于籠統(tǒng)的名稱桐猬。這些名稱可能導致對 API 概念的誤解麦撵。相反,應選擇能準確描述 API 概念的名稱溃肪。這對定義一階 API 元素(例如資源)的名稱尤其重要免胃。沒有要避免使用的名稱的明確列表,因為每個名稱都必須放在其他名稱的上下文中進行評估惫撰。實例羔沙、信息和服務(wù)是過去有問題的名稱的示例。所選擇的名稱應清楚地描述 API 概念(例如:什么的實例厨钻?)扼雏,并將其與其他相關(guān)概念區(qū)分開(例如:“alert”是指規(guī)則坚嗜、信號還是通知?)诗充。
- 仔細考慮是否使用可能與常用編程語言中的關(guān)鍵字相沖突的名稱苍蔬。您可以使用這些名稱,但在 API 審核期間可能會觸發(fā)額外的審查蝴蜓。因此應謹慎使用碟绑。
2.9 認證和授權(quán)(Authentication & Authorization)
一般來說,讓任何人隨意訪問公開的 API 是不好的做法茎匠。驗證和授權(quán)是兩件事情:
- 驗證(Authentication)是為了確定用戶是其申明的身份格仲,比如提供賬戶的密碼。不然的話诵冒,任何人偽造成其他身份(比如其他用戶或者管理員)是非常危險的
- 授權(quán)(Authorization)是為了保證用戶有對請求資源特定操作的權(quán)限抓狭。比如用戶的私人信息只能自己能訪問,其他人無法看到造烁;有些特殊的操作只能管理員可以操作,其他用戶有只讀的權(quán)限等等
如果沒有通過驗證(提供的用戶名和密碼不匹配午笛,token 不正確等)惭蟋,需要返回 401 Unauthorized 狀態(tài)碼,并在 body 中說明具體的錯誤信息药磺;而沒有被授權(quán)訪問的資源操作告组,需要返回 403 Forbidden 狀態(tài)碼,還有詳細的錯誤信息癌佩。
NOTES: 借鑒于 Github木缝,它對某些用戶未被授權(quán)訪問的資源操作返回 404 Not Found ,目的是為了防止私有資源的泄露(比如黑客可以自動化試探用戶的私有資源围辙,返回 403 的話我碟,就等于告訴黑客用戶有這些私有的資源)。
2.10 限流(RateLimit)
如果對訪問的次數(shù)不加控制姚建,很可能會造成 API 被濫用矫俺,甚至被 DDOS 攻擊 。根據(jù)使用者不同的身份對其進行限流掸冤,可以防止這些情況厘托,減少服務(wù)器的壓力。
對用戶的請求限流之后稿湿,要有方法告訴用戶它的請求使用情況铅匹,本文檔推薦使用的三個相關(guān)的頭部:
-
X-RateLimit-Limit
: 用戶每個小時允許發(fā)送請求的最大值 -
X-RateLimit-Remaining
:當前時間窗口剩下的可用請求數(shù)目 -
X-RateLimit-Rest
: 時間窗口重置的時候,到這個時間點可用的請求數(shù)量就會變成X-RateLimit-Limit
的值
舉例:
X-Ratelimit-Limit: 18000
X-Ratelimit-Remaining: 17995
X-Ratelimit-Reset: 1590570990
如果允許沒有登錄的用戶使用 API(可以讓用戶試用)饺藤,可以把 X-RateLimit-Limit
的值設(shè)置得很小包斑,比如 60
流礁。沒有登錄的用戶是按照請求的 IP 來確定的,而登錄的用戶按照認證后的信息來確定身份舰始。
對于超過流量的請求崇棠,可以返回 429 Too many requests 狀態(tài)碼,并附帶錯誤信息丸卷。
2.11 編寫優(yōu)秀的文檔
API 最終是給人使用的枕稀,不管是公司內(nèi)部,還是公開的 API 都是一樣谜嫉。即使我們遵循了上面提到的所有規(guī)范萎坷,設(shè)計的 API 非常優(yōu)雅,用戶還是不知道怎么使用我們的 API沐兰。最后一步哆档,但非常重要的一步是:為你的 API 編寫優(yōu)秀的文檔。
對每個請求以及返回的參數(shù)給出說明住闯,最好給出一個詳細而完整地示例瓜浸,提醒用戶需要注意的地方……反正目標就是用戶可以根據(jù)你的文檔就能直接使用 API,而不是要發(fā)郵件給你比原,或者跑到你的座位上問你一堆問題插佛。