日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

RESTful API書寫規(guī)范

 

基于一些不錯的RESTful開發(fā)組件,可以快速的開發(fā)出不錯的RESTful API,但如果不了解開發(fā)規(guī)范的、健壯的RESTful API的基本面,即便優(yōu)秀的RESTful開發(fā)組件擺在面前,也無法很好的理解和使用。下文Gevin結(jié)合自己的實踐經(jīng)驗,整理了從零開始開發(fā)RESTful API的核心要點,完善的RESTful開發(fā)組件基本都會包含全部或大部分要點,對于支持不夠到位的要點,我們也可以自己寫代碼實現(xiàn)。

1. Request 和 Response

RESTful API的開發(fā)和使用,無非是客戶端向服務(wù)器發(fā)請求(request),以及服務(wù)器對客戶端請求的響應(yīng)(response)。本真RESTful架構(gòu)風(fēng)格具有統(tǒng)一接口的特點,即,使用不同的http方法表達不同的行為:

  • GET(SELECT):從服務(wù)器取出資源(一項或多項)
  • POST(CREATE):在服務(wù)器新建一個資源
  • PUT(UPDATE):在服務(wù)器更新資源(客戶端提供完整資源數(shù)據(jù))
  • PATCH(UPDATE):在服務(wù)器更新資源(客戶端提供需要修改的資源數(shù)據(jù))
  • DELETE(DELETE):從服務(wù)器刪除資源

客戶端會基于GET方法向服務(wù)器發(fā)送獲取數(shù)據(jù)的請求,基于PUT或PATCH方法向服務(wù)器發(fā)送更新數(shù)據(jù)的請求等,服務(wù)端在設(shè)計API時,也要按照相應(yīng)規(guī)范來處理對應(yīng)的請求,這點現(xiàn)在應(yīng)該已經(jīng)成為所有RESTful API的開發(fā)者的共識了,而且各web框架的request類和response類都很強大,具有合理的默認設(shè)置和靈活的定制性,Gevin在這里僅準備強調(diào)一下響應(yīng)這些request時,常用的Response要包含的數(shù)據(jù)和狀態(tài)碼(status code),不完善的內(nèi)容,歡迎大家補充:

  • 當(dāng)GET, PUT和PATCH請求成功時,要返回對應(yīng)的數(shù)據(jù),及狀態(tài)碼200,即SUCCESS
  • 當(dāng)POST創(chuàng)建數(shù)據(jù)成功時,要返回創(chuàng)建的數(shù)據(jù),及狀態(tài)碼201,即CREATED
  • 當(dāng)DELETE刪除數(shù)據(jù)成功時,不返回數(shù)據(jù),狀態(tài)碼要返回204,即NO CONTENT
  • 當(dāng)GET 不到數(shù)據(jù)時,狀態(tài)碼要返回404,即NOT FOUND
  • 任何時候,如果請求有問題,如校驗請求數(shù)據(jù)時發(fā)現(xiàn)錯誤,要返回狀態(tài)碼 400,即BAD REQUEST
  • 當(dāng)API 請求需要用戶認證時,如果request中的認證信息不正確,要返回狀態(tài)碼 401,即NOT AUTHORIZED
  • 當(dāng)API 請求需要驗證用戶權(quán)限時,如果當(dāng)前用戶無相應(yīng)權(quán)限,要返回狀態(tài)碼 403,即FORBIDDEN

最后,關(guān)于Request 和 Response,不要忽略了http header中的Content-Type。以json為例,如果API要求客戶端發(fā)送request時要傳入json數(shù)據(jù),則服務(wù)器端僅做好json數(shù)據(jù)的獲取和解析即可,但如果服務(wù)端支持多種類型數(shù)據(jù)的傳入,如同時支持json和form-data,則要根據(jù)客戶端發(fā)送請求時header中的Content-Type,對不同類型是數(shù)據(jù)分別實現(xiàn)獲取和解析;如果API響應(yīng)客戶端請求后,需要返回json數(shù)據(jù),需要在header中添加Content-Type=Application/json。

2. Serialization 和 Deserialization

Serialization 和 Deserialization即序列化和反序列化。RESTful API以規(guī)范統(tǒng)一的格式作為數(shù)據(jù)的載體,常用的格式為json或xml,以json格式為例,當(dāng)客戶端向服務(wù)器發(fā)請求時,或者服務(wù)器相應(yīng)客戶端的請求,向客戶端返回數(shù)據(jù)時,都是傳輸json格式的文本,而在服務(wù)器內(nèi)部,數(shù)據(jù)處理時基本不用json格式的字符串,而是native類型的數(shù)據(jù),最典型的如類的實例,即對象(object),json僅為服務(wù)器和客戶端通信時,在網(wǎng)絡(luò)上傳輸?shù)臄?shù)據(jù)的格式,服務(wù)器和客戶端內(nèi)部,均存在將json轉(zhuǎn)為native類型數(shù)據(jù)和將native類型數(shù)據(jù)轉(zhuǎn)為json的需求,其中,將native類型數(shù)據(jù)轉(zhuǎn)為json即為序列化,將json轉(zhuǎn)為native類型數(shù)據(jù)即為反序列化。雖然某些開發(fā)語言,如Python,其原生數(shù)據(jù)類型list和dict能輕易實現(xiàn)序列化和反序列化,但對于復(fù)雜的API,內(nèi)部實現(xiàn)時總會以對象作為數(shù)據(jù)的載體,因此,確保序列化和反序列化方法的實現(xiàn),是開發(fā)RESTful API最重要的一步準備工作

題外話,序列化和反序列化的便捷,造就了RESTful API跨平臺的特點,使得REST取代RPC成為Web Service的主流

序列化和反序列化是RESTful API開發(fā)中的一項硬需求,所以幾乎每一種常用的開發(fā)語言都會有一個或多個優(yōu)秀的開源庫,來實現(xiàn)序列化和反序列化,因此,我們在開發(fā)RESTful API時,沒必要制造重復(fù)的輪子,選一個好用的庫即可,如python中的marshmallow,如果基于Django開發(fā),Django REST Framework中的serializer即可。

3. Validation

Validation即數(shù)據(jù)校驗,是開發(fā)健壯RESTful API中另一個重要的一環(huán)。仍以json為例,當(dāng)客戶端向服務(wù)器發(fā)出post, put或patch請求時,通常會同時給服務(wù)器發(fā)送json格式的相關(guān)數(shù)據(jù),服務(wù)器在做數(shù)據(jù)處理之前,先做數(shù)據(jù)校驗,是最合理和安全的前后端交互。如果客戶端發(fā)送的數(shù)據(jù)不正確或不合理,服務(wù)器端經(jīng)過校驗后直接向客戶端返回400錯誤及相應(yīng)的數(shù)據(jù)錯誤信息即可。常見的數(shù)據(jù)校驗包括:

  • 數(shù)據(jù)類型校驗,如字段類型如果是int,那么給字段賦字符串的值則報錯
  • 數(shù)據(jù)格式校驗,如郵箱或密碼,其賦值必須滿足相應(yīng)的正則表達式,才是正確的輸入數(shù)據(jù)
  • 數(shù)據(jù)邏輯校驗,如數(shù)據(jù)包含出生日期和年齡兩個字段,如果這兩個字段的數(shù)據(jù)不一致,則數(shù)據(jù)校驗失敗

以上三種類型的校驗,數(shù)據(jù)邏輯校驗最為復(fù)雜,通常涉及到多個字段的配合,或者要結(jié)合用戶和權(quán)限做相應(yīng)的校驗。Validation雖然是RESTful API 編寫中的一個可選項,但它對API的安全、服務(wù)器的開銷和交互的友好性而言,都具有重要意義,因此,Gevin建議,開發(fā)一套完善的RESTful API時,Validation的實現(xiàn)必不可少。

4. Authentication 和 Permission

Authentication指用戶認證,Permission指權(quán)限機制,這兩點是使RESTful API 強大、靈活和安全的基本保障。

常用的認證機制是Basic Auth和OAuth,RESTful API 開發(fā)中,除非API非常簡單,且沒有潛在的安全性問題,否則,認證機制是必須實現(xiàn)的,并應(yīng)用到API中去。Basic Auth非常簡單,很多框架都集成了Basic Auth的實現(xiàn),自己寫一個也能很快搞定,OAuth目前已經(jīng)成為企業(yè)級服務(wù)的標配,其相關(guān)的開源實現(xiàn)方案非常豐富(更多)。

我在《RESTful 架構(gòu)風(fēng)格概述》中,對認證機制做了更加詳細的描述,有興趣的同學(xué)不妨閱讀相關(guān)章節(jié)。

權(quán)限機制是對API請求更近一步的限制,只有通過認證的用戶符合權(quán)限要求,才能訪問API。權(quán)限機制的具體實現(xiàn)通常依賴于系統(tǒng)的業(yè)務(wù)邏輯和應(yīng)用場景,generally speaking,常用的權(quán)限機制主要包含全局型的和對象型的,全局型的權(quán)限機制,主要指通過為用戶賦予權(quán)限,或者為用戶賦予角色或劃分到用戶組,然后為角色或用戶組賦予權(quán)限的方式來實現(xiàn)權(quán)限控制,對象型的權(quán)限機制,主要指權(quán)限控制的顆粒度在object上,用戶對某個具體對象的訪問、修改、刪除或其行為,要單獨在該對象上為用戶賦予相關(guān)權(quán)限來實現(xiàn)權(quán)限控制。

全局型的權(quán)限機制容易理解,實現(xiàn)也簡單,有很多開源庫可做備選方案,不少完善的web開發(fā)框架,也會集成相關(guān)的權(quán)限邏輯,object permission 相對難復(fù)雜一點,但也有很多典型的應(yīng)用場景,如多人博客系統(tǒng)中,作者對自己文章的編輯權(quán)限即為object permission,其對應(yīng)的開源庫也有很多。

注: 我寫過一篇《Django權(quán)限機制的實現(xiàn)》,Django 開發(fā)者可做延伸閱讀。

開發(fā)一套完整的RESTful API,權(quán)限機制必須納入考慮范圍,雖然權(quán)限機制的具體實現(xiàn)依賴于業(yè)務(wù),權(quán)限機制本身,是有典型的模式存在的,需要開發(fā)者掌握基本的權(quán)限機制實現(xiàn)方案,以便隨時應(yīng)用到API中去。

5. CORS

CORS即Cross-origin resource sharing,在RESTful API開發(fā)中,主要是為js服務(wù)的,解決JAVAscript 調(diào)用 RESTful API時的跨域問題。

由于固有的安全機制,js的跨域請求時是無法被服務(wù)器成功響應(yīng)的。現(xiàn)在前后端分離日益成為web開發(fā)主流方式的大趨勢下,后臺逐漸趨向指提供API服務(wù),為各客戶端提供數(shù)據(jù)及相關(guān)操作,而網(wǎng)站的開發(fā)全部交給前端搞定,網(wǎng)站和API服務(wù)很少部署在同一臺服務(wù)器上并使用相同的端口,js的跨域請求時普遍存在的,開發(fā)RESTful API時,通常都要考慮到CORS功能的實現(xiàn),以便js能正常使用API。

目前各主流web開發(fā)語言都有很多優(yōu)秀的實現(xiàn)CORS的開源庫,我們在開發(fā)RESTful API時,要注意CORS功能的實現(xiàn),直接拿現(xiàn)有的輪子來用即可。

更多關(guān)于CORS的介紹,有興趣的同學(xué)可以查看阮一峰老師的跨域資源共享 CORS 詳解

6. URL Rules

RESTful API 是寫給開發(fā)者來消費的,其命名和結(jié)構(gòu)需要有意義。因此,在設(shè)計和編寫URL時,要符合一些規(guī)范。Url rules 可以單獨寫一篇博客來詳細闡述,本文只列出一些關(guān)鍵點。

6.1 Version your API

規(guī)范的API應(yīng)該包含版本信息,在RESTful API中,最簡單的包含版本的方法是將版本信息放到url中,如:

/api/v1/posts/
/api/v1/drafts/
/api/v2/posts/
/api/v2/drafts/

另一種優(yōu)雅的做法是,使用HTTP header中的accept來傳遞版本信息,這也是GitHub API 采取的策略。

6.2 Use nouns, not verbs

RESTful API 中的url是指向資源的,而不是描述行為的,因此設(shè)計API時,應(yīng)使用名詞而非動詞來描述語義,否則會引起混淆和語義不清。即:

# Bad APIs
/api/getArticle/1/
/api/updateArticle/1/
/api/deleteArticle/1/

上面四個url都是指向同一個資源的,雖然一個資源允許多個url指向它,但不同的url應(yīng)該表達不同的語義,上面的API可以優(yōu)化為:

# Good APIs
/api/Article/1/

article 資源的獲取、更新和刪除分別通過 GET, PUT 和 DELETE方法請求API即可。試想,如果url以動詞來描述,用PUT方法請求 /api/deleteArticle/1/ 會感覺多么不舒服。

6.3 GET and HEAD should always be safe

RFC2616已經(jīng)明確指出,GET和HEAD方法必須始終是安全的。例如,有這樣一個不規(guī)范的API:

# The following api is used to delete articles
# [GET]
/api/deleteArticle?id=1

試想,如果搜索引擎訪問了上面url會如何?

6.4 Nested resources routing

如果要獲取一個資源子集,采用 nested routing 是一個優(yōu)雅的方式,如,列出所有文章中屬于Gevin編寫的文章:

# List Gevin's articles
/api/authors/gevin/articles/

獲取資源子集的另一種方式是基于filter(見下面章節(jié)),這兩種方式都符合規(guī)范,但語義不同:如果語義上將資源子集看作一個獨立的資源集合,則使用 nested routing 感覺更恰當(dāng),如果資源子集的獲取是出于過濾的目的,則使用filter更恰當(dāng)。

至于編寫RESTful API時到底應(yīng)采用哪種方式,則仁者見仁,智者見智,語義上說的通即可。

6.5 Filter

對于資源集合,可以通過url參數(shù)對資源進行過濾,如:

# List Gevin's articles
/api/articles?author=gevin

分頁就是一種最典型的資源過濾。

6.6 Pagination

對于資源集合,分頁獲取是一種比較合理的方式。如果基于開發(fā)框架(如Django REST Framework),直接使用開發(fā)框架中的分頁機制即可,如果是自己實現(xiàn)分頁機制,Gevin的策略是:

返回資源集合是,包含與分頁有關(guān)的數(shù)據(jù)如下:

{
 "page": 1, # 當(dāng)前是第幾頁
 "pages": 3, # 總共多少頁
 "per_page": 10, # 每頁多少數(shù)據(jù)
 "has_next": true, # 是否有下一頁數(shù)據(jù)
 "has_prev": false, # 是否有前一頁數(shù)據(jù)
 "total": 27 # 總共多少數(shù)據(jù)
}

當(dāng)想API請求資源集合時,可選的分頁參數(shù)為:

參數(shù)含義page當(dāng)前是第幾頁,默認為1per_page每頁多少條記錄,默認為系統(tǒng)默認值

另外,系統(tǒng)內(nèi)還設(shè)置一個per_page_max字段,用于標記系統(tǒng)允許的每頁最大記錄數(shù),當(dāng)per_page值大于 per_page_max 值時,每頁記錄條數(shù)為 per_page_max。

6.7 Url design tricks

(1)Url是區(qū)分大小寫的,這點經(jīng)常被忽略,即:

  • /Posts
  • /posts

上面這兩個url是不同的兩個url,可以指向不同的資源

(2)Back forward Slash (/)

目前比較流行的API設(shè)計方案,通常建議url以/作為結(jié)尾,如果API GET請求中,url不以/結(jié)尾,則重定向到以/結(jié)尾的API上去(這點現(xiàn)在的web框架基本都支持),因為有沒有 /,也是兩個url,即:

  • /posts/
  • /posts

這也是兩個不同的url,可以對應(yīng)不同的行為和資源

(3)連接符 - 和 下劃線 _

RESTful API 應(yīng)具備良好的可讀性,當(dāng)url中某一個片段(segment)由多個單詞組成時,建議使用 - 來隔斷單詞,而不是使用 _,即:

# Good
/api/featured-post/
# Bad
/api/featured_post/

這主要是因為,瀏覽器中超鏈接顯示的默認效果是,文字并附帶下劃線,如果API以_隔斷單詞,二者會重疊,影響可讀性。

總結(jié)

編寫本文的初衷,是為了整理一套從零開始編寫規(guī)范、安全的RESTful API的基本思路。本文介紹了開發(fā)RESTful API時,要考慮的基本內(nèi)容,對于類似Flask這種天生支持RESTful風(fēng)格的web框架,不依賴其他RESTful第三方庫開發(fā)RESTful 服務(wù)時,可以從本文內(nèi)容入手;不少強大的RESTful 庫,雖然其相關(guān)接口基本涵蓋了本文的全部或大部分內(nèi)容,但本文的總結(jié),相信對這些庫的理解和使用也是有幫助的。

分享到:
標簽:RESTful
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定