編譯自:RESTful API Designing guidelines?—?The best practices
譯者:開(kāi)源中國(guó) - ismdeep, Tocy, 無(wú)若, butta, 昌偉兄, osbertngok
Facebook、谷歌、Github、Netflix 和幾個(gè)其他的科技巨頭已經(jīng)允許開(kāi)發(fā)者和其產(chǎn)品通過(guò) API 調(diào)用他們的數(shù)據(jù),并為他們提供平臺(tái)。即使你不是寫(xiě) API 的專(zhuān)業(yè)人士,擁有精美的 API 也對(duì)你的應(yīng)用程序有好處。
關(guān)于設(shè)計(jì) API 的最好方法,網(wǎng)絡(luò)上有較長(zhǎng)一段時(shí)間的爭(zhēng)論,但官方也沒(méi)有對(duì)此給出解釋。
API 是一個(gè)接口,通過(guò)它許多開(kāi)發(fā)者可與數(shù)據(jù)交互。 設(shè)計(jì)優(yōu)良的 API 使用起來(lái)很方便,并給開(kāi)發(fā)者的工作帶來(lái)便利。 API 是開(kāi)發(fā)者的 GUI,如果它設(shè)計(jì)不合理,開(kāi)發(fā)者會(huì)將它替換。所以,開(kāi)發(fā)者的經(jīng)驗(yàn)是衡量 API 質(zhì)量的最重要的指標(biāo)。
"API就像一個(gè)在舞臺(tái)上表演的藝術(shù)家,其用戶(hù)就是其觀眾"
1) 術(shù)語(yǔ)
以下是與 REST API 相關(guān)的重要術(shù)語(yǔ):
資源(Resource) 是一個(gè)對(duì)象或?qū)δ澄锏谋硎尽K幸恍┫嚓P(guān)聯(lián)的數(shù)據(jù),并有一組方法進(jìn)行操作。 例如:動(dòng)物,學(xué)校和員工是資源。這些資源都有著刪除,添加,更新操作。
集合(Collection)是一系列資源,例如:公司集合是很多公司的集合。
URL(統(tǒng)一資源定位符)是一種路徑,可以通過(guò)它定位資源并且也可以對(duì)它執(zhí)行一些動(dòng)作。
2) API 端點(diǎn)(路徑)
為了更好理解,我們給公司寫(xiě) API,這些公司都有一些員工。/getAllEmployees 是對(duì)員工列表進(jìn)行回應(yīng)的 API。公司其他 API 大致如下:
/addNewEmployee
/updateEmployee
/deleteEmployee
/deleteAllEmployees
/promoteEmployee
/promoteAllEmployees
并且將有大量的和這些操作不同的 API 端點(diǎn),它們包含大量冗余的行為。因此,當(dāng) API 數(shù)量增加時(shí),這些 API 端點(diǎn)將很難維護(hù)。
哪里不對(duì)?
每個(gè) URL 代表一種資源(Resource),所以 URL 中只能有名詞,不能有動(dòng)詞。 API 路徑 /addNewEmployee 包含了操作 addNew 和資源名稱(chēng)?Employee。
那么怎樣算是正確的方式?
/companies 是一個(gè)很好的不包含操作的例子。但是問(wèn)題來(lái)了,我們?cè)撛鯓痈嬖V服務(wù)器我們要進(jìn)行的操作呢?新增,刪除,還是更新?
這時(shí)HTTP 方法(GET,POST,DELETE,PUT)(也稱(chēng)為動(dòng)詞)就可以起到作用了。
資源在 API 端點(diǎn)中應(yīng)該總是復(fù)數(shù),如果我們想訪(fǎng)問(wèn)資源的一個(gè)實(shí)例,我們可以傳遞 URL 中的 id。
方法 GET 路徑 /companies 是獲取所有公司的列表。
方法 GET?路徑 /companies/34 是獲取公司34的詳細(xì)信息。
方法 DELETE?路徑 /companies/34 是刪除公司34。
在其他的一些使用案例中,如果我們有一些資源在某個(gè)資源之下,例如,一個(gè)公司的員工,那么在這樣的例子中 API 的 endpoint(端點(diǎn)) 就應(yīng)該是這樣的:
GET /companies/3/employees 可以取得編號(hào)為3的公司的員工列表
GET /companies/3/employees/45?可以取得編號(hào)為3的公司的45號(hào)員工的細(xì)節(jié)信息
DELETE /companies/3/employees/45 可以刪除編號(hào)為3的公司的45號(hào)員工
POST /companies 可以創(chuàng)建一個(gè)新公司并返回新創(chuàng)建公司的細(xì)節(jié)信息
現(xiàn)在這樣,API 是不是更嚴(yán)謹(jǐn)和一致了呢?
結(jié)論:路徑應(yīng)該包含資源的復(fù)數(shù)形式,HTTP 方法應(yīng)該定義成各種行為在資源上執(zhí)行。
3) HTTP 方法 (動(dòng)詞)
HTTP 定義了幾組方法,這些方法給出了對(duì)資源要執(zhí)行的操作類(lèi)型。
URL 是一個(gè)句子,其中資源是名詞,HTTP 方法是動(dòng)詞。
主要的HTTP方法如下:
GET 方法從資源請(qǐng)求數(shù)據(jù),不產(chǎn)生多余結(jié)果。
例如: /companies/3/employees 會(huì)返回公司3的所有雇員列表。
POST 方法請(qǐng)求服務(wù)器在數(shù)據(jù)庫(kù)中創(chuàng)建資源,這主要用于提交 Web 表單時(shí)。
例如: /companies/3/employees 創(chuàng)建一個(gè)公司3的新雇員。
POST 是非冪等的,這意味著多個(gè)請(qǐng)求將會(huì)有不同的效果。
PUT 方法請(qǐng)求服務(wù)器更新資源或創(chuàng)建資源(如果不存在的話(huà))。
例如: /companies/3/employees/john 將請(qǐng)求服務(wù)器在公司3的雇員集合中更新或在不存在的情況下創(chuàng)建關(guān)于 john 的資源。
PUT 是冪等的,這意味著多次請(qǐng)求具有相同的效果。
DELETE 方法將請(qǐng)求的資源或?qū)嵗龔臄?shù)據(jù)庫(kù)中刪除。
例如: /companies/3/employees/john/ 將請(qǐng)求服務(wù)器從公司3的雇員集中刪除 john 資源。
HTTP 中還有很多其他方法,我們將在另一篇文章中討論。
4) HTTP 響應(yīng)狀態(tài)碼
當(dāng)客戶(hù)端通過(guò) API 向服務(wù)器發(fā)起請(qǐng)求時(shí),無(wú)論請(qǐng)求是失敗的、通過(guò)的還是錯(cuò)誤的,客戶(hù)端應(yīng)該獲得反饋。HTTP 狀態(tài)碼是一堆標(biāo)準(zhǔn)化的數(shù)值碼,在不同的情況下具有不同的解釋。服務(wù)器應(yīng)始終返回正確的狀態(tài)碼。
以下是 HTTP 狀態(tài)碼的主要分類(lèi):
2xx (成功類(lèi)別)
這些狀態(tài)代碼表示請(qǐng)求的操作已被服務(wù)器接收到并成功處理。
200 Ok:標(biāo)準(zhǔn)的 HTTP 響應(yīng),表示 GET、PUT 或 POST 的處理成功。
201 Created:在創(chuàng)建新實(shí)例時(shí),應(yīng)返回此狀態(tài)代碼。例如,使用 POST 方法創(chuàng)建一個(gè)新的實(shí)例,應(yīng)該始終返回 201 狀態(tài)碼。
204 內(nèi)容不存在:表示請(qǐng)求已被成功處理,但并未返回任何內(nèi)容。
DELETE算是其中一個(gè)很好的例子。
API DELETE /companies/43/employees/2?將刪除員工 2,作為響應(yīng),我們不需要在該 API 的響應(yīng)正文中的任何數(shù)據(jù),因?yàn)槲覀兠鞔_地要求系統(tǒng)將其刪除。如果有任何錯(cuò)誤發(fā)生,例如,如果員工 2 在數(shù)據(jù)庫(kù)中不存在,那么響應(yīng)碼將不是 2xx 對(duì)應(yīng)的成功類(lèi)別,而是 4xx 客戶(hù)端錯(cuò)誤類(lèi)別。
3xx (重定向類(lèi)別)
304 未修改:表示客戶(hù)端的響應(yīng)已經(jīng)在其緩存中。 因此,不需要再次傳送相同的數(shù)據(jù)。
4xx (客戶(hù)端錯(cuò)誤類(lèi)別)
這些狀態(tài)代碼表示客戶(hù)端發(fā)起了錯(cuò)誤的請(qǐng)求。
400 錯(cuò)誤請(qǐng)求:表示客戶(hù)端的請(qǐng)求沒(méi)有被處理,因?yàn)榉?wù)器不能理解客戶(hù)端請(qǐng)求的是什么。
401 未授權(quán):表示客戶(hù)端不被允許訪(fǎng)問(wèn)該資源,需要使用指定憑證重新請(qǐng)求。
403 禁止訪(fǎng)問(wèn):表示請(qǐng)求是有效的并且客戶(hù)端已通過(guò)身份驗(yàn)證,但客戶(hù)端不被允許以任何理由訪(fǎng)問(wèn)對(duì)應(yīng)頁(yè)面或資源。 例如有時(shí)授權(quán)的客戶(hù)端不被允許訪(fǎng)問(wèn)服務(wù)器上的目錄。
404 未找到:表示所請(qǐng)求的資源現(xiàn)在不可用。
410 資源不可用:表示所請(qǐng)求的資源后續(xù)不再可用,該資源已被移動(dòng)。
5xx(服務(wù)器錯(cuò)誤類(lèi)別)
500是服務(wù)器內(nèi)部錯(cuò)誤,表示請(qǐng)求已經(jīng)被接收到了,但服務(wù)器被要求處理某些未預(yù)設(shè)的請(qǐng)求而完全混亂。
503服務(wù)不可用表示服務(wù)器已關(guān)閉或無(wú)法接收和處理請(qǐng)求。大多數(shù)情況是服務(wù)器正在進(jìn)行維護(hù)。
5) 字段套管約定
您可以遵循任何套管約定,但要確保其在應(yīng)用程序中一致。如果請(qǐng)求主體或響應(yīng)類(lèi)型是JSON,那么請(qǐng)按照camelCase(駝峰命名法)來(lái)保持一致。
6) 搜索、排序、過(guò)濾和分頁(yè)
這些行為都只是針對(duì)一個(gè)數(shù)據(jù)集進(jìn)行的查詢(xún)。由于還沒(méi)有一套新的 API 來(lái)處理這些行為。因此,我們需要向 GET 方法的 API 附加查詢(xún)參數(shù)。
我們來(lái)理解幾個(gè)例子看它們是如何實(shí)現(xiàn)這些行為的。
排序(sorting),客戶(hù)端想要獲得排序后的公司列表,GET /companies 端點(diǎn)應(yīng)當(dāng)接受多個(gè)查詢(xún)排序參數(shù)。
例如,GET /companies?sort=rank_asc 將根據(jù)等級(jí)以升序的方式對(duì)公司進(jìn)行排序。
過(guò)濾(Filtering),用來(lái)過(guò)濾數(shù)據(jù)集,我們可以通過(guò)查詢(xún)參數(shù)傳遞不同的選項(xiàng)。
例如,GET /companies?category=banking&location=india 將根據(jù)公司類(lèi)別為銀行以及所處位置為印度來(lái)過(guò)濾公司的列表數(shù)據(jù)。
搜索(Searching),當(dāng)需要在公司列表中搜索公司名稱(chēng)時(shí),API 端點(diǎn)應(yīng)當(dāng)是 GET /companies?search=Digital Mckinsey。
分頁(yè)(Pagination),當(dāng)數(shù)據(jù)集太大時(shí),我們將數(shù)據(jù)集分成更小的塊,這樣有助于提高性能,并且更易于處理響應(yīng)。 例如,GET /companies?page=23 表示獲取第 23 頁(yè)的公司列表。
如果在 GET 方法中附加了很多查詢(xún)參數(shù),會(huì)造成 URI 太長(zhǎng),服務(wù)器可能會(huì)響應(yīng) 414 的 HTTP 狀態(tài),表示這個(gè) URI 太長(zhǎng),在這種情況下,我們也可以將參數(shù)傳遞給 POST 方法的請(qǐng)求體中。
7) 版本控制
當(dāng)你的 API 被開(kāi)始被廣泛使用后,突然升級(jí)API會(huì)打破現(xiàn)有的產(chǎn)品、服務(wù)。
這里有個(gè)一個(gè)很好的例子,它的路徑中有API的版本號(hào)。如果有任何重大的中斷更新,我們可以將新的API集命名為v2或v1.x.x
這些指南是根據(jù)我的開(kāi)發(fā)經(jīng)驗(yàn)編寫(xiě)的。我很想知道你對(duì)上述幾點(diǎn)的看法。