RESTfulAPI設(shè)計(jì)規(guī)范方案_第1頁(yè)
RESTfulAPI設(shè)計(jì)規(guī)范方案_第2頁(yè)
RESTfulAPI設(shè)計(jì)規(guī)范方案_第3頁(yè)
RESTfulAPI設(shè)計(jì)規(guī)范方案_第4頁(yè)
RESTfulAPI設(shè)計(jì)規(guī)范方案_第5頁(yè)
已閱讀5頁(yè),還剩20頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

背景目前互聯(lián)網(wǎng)上充滿著大量的關(guān)于RESTfulAPI〔為方便,下文中“RESTfulAPI〞API格式如何?你的API是否應(yīng)該參加版本信息?當(dāng)你開場(chǎng)寫一個(gè)app的時(shí)候,特別是后端模型局部已經(jīng)寫完的時(shí)候,你不得不殫精竭慮的設(shè)計(jì)和實(shí)現(xiàn)自己app的publicAPI局部。因?yàn)橐坏┌l(fā)布,對(duì)外發(fā)布的API將會(huì)很難改變。SupportedFuAPI角度來解決上面提到的問題。我希望可以設(shè)計(jì)出容易使用,容易部署,并且足夠靈活的API,本文因此而生。API設(shè)計(jì)的根本要求PI如果覺得不適宜,我不會(huì)遵從標(biāo)準(zhǔn)。當(dāng)然作為設(shè)計(jì)的根底,幾個(gè)必須的原那么還是要遵守的:1.當(dāng)標(biāo)準(zhǔn)合理的時(shí)候遵守標(biāo)準(zhǔn)。2.API應(yīng)該對(duì)程序員友好,并且在瀏覽器地址欄容易輸入。3.API應(yīng)該簡(jiǎn)單,直觀,容易使用的同時(shí)優(yōu)雅。4.API應(yīng)該具有足夠的靈活性來支持上層ui。5.API設(shè)計(jì)權(quán)衡上述幾個(gè)原那么。戶體驗(yàn)! 使用RESTfulURLs和action.雖然前面我說沒有一個(gè)萬(wàn)能的API設(shè)計(jì)標(biāo)準(zhǔn)。但確實(shí)有一個(gè)被普遍成認(rèn)和遵守:RESTfu設(shè)計(jì)原那么。它被RoyFelding提出〔在他的〞基于網(wǎng)絡(luò)的軟件架構(gòu)“論文中第五章〕。而REST的核心原那么是將你的API拆分為邏輯上的資源。這些資源通過被操作〔GET,POST,PUT,DELETE〕。?顯然從API用戶的角度來看,〞資源“應(yīng)該是個(gè)名詞。即使你的內(nèi)部數(shù)據(jù)模型和資源已經(jīng)有了很好的對(duì)應(yīng),API設(shè)計(jì)的時(shí)候你仍然不需要把它們一對(duì)一的都暴露出來。這里的關(guān)鍵是隱藏內(nèi)部資源,暴露必需的外部資源。一旦定義好了要暴露的資源,你可以定義資源上允許的操作,以及這些操作和你的API的對(duì)應(yīng)關(guān)系:?GET/tickets#獲取ticket列表?GET/tickets/12#查看某個(gè)具體的ticket?POST/tickets#新建一個(gè)ticket?PUT/tickets/12#更新ticket12.?DELETE/tickets/12#刪除ticekt12可以看出使用REST的好處在于可以充分利用的強(qiáng)大實(shí)現(xiàn)對(duì)資源的CURD功能。而這里你只需要一個(gè)endpoint:/tickets,再?zèng)]有其他什么命名規(guī)那么和url規(guī) 這個(gè)endpoint的單數(shù)復(fù)數(shù)一個(gè)可以遵從的規(guī)那么是:雖然看起來使用復(fù)數(shù)來描述某一個(gè)資源實(shí)例看起來別扭,但是統(tǒng)一所有的endpoint,使用復(fù)數(shù)使得你的URL更加規(guī)整。這讓API使用者更加容易理解,對(duì)開發(fā)者來說也更容易實(shí)現(xiàn)。如何處理關(guān)聯(lián)?關(guān)于如何處理資源之間的管理REST原那么也有相關(guān)的描述:?GET/tickets/12/messages-Retrieveslistofmessagesforticket#12?GET/tickets/12/messages/5-Retrievesmessage#5forticket#12?POST/tickets/12/messages-Createsanewmessageinticket#12?PUT/tickets/12/messages/5-Updatesmessage#5forticket#12?PATCH/tickets/12/messages/5-Partiallyupdatesmessage#5forticket#12?DELETE/tickets/12/messages/5-Deletesmessage#5forticket#12其中,如果這種關(guān)聯(lián)和資源獨(dú)立,那么我們可以在資源的輸出表示中保存相應(yīng)資源的endpoint。然后API的使用者就可以通過點(diǎn)擊鏈接找到相關(guān)的資源。如果關(guān)聯(lián)和資源聯(lián)系嚴(yán)密。資源的輸出表示就應(yīng)該直接保存相應(yīng)資源信息?!怖邕@里如果message資源是獨(dú)立存在的,那么上面GET/tickets/12/messages就會(huì)返回相應(yīng)message的鏈接;相反的如果message不獨(dú)立存在,他和ticket依附存在,那么上面的API調(diào)用返回直接返回message信息〕不符合CURD的操作對(duì)這個(gè)令人困惑的問題,下面是一些解決方法: action的時(shí)候,你可以把a(bǔ)ctive對(duì)應(yīng)并且取消星操作:DELETE/gists/:id/star.3.有時(shí)候action實(shí)在沒有難以和某個(gè)資源對(duì)應(yīng)上例如search。那就這么辦吧。理解〕。只要注意在文檔中寫清楚就可以了。永遠(yuǎn)使用SSL毫無例外,永遠(yuǎn)都要使用SSL。你的應(yīng)用不知道要被誰(shuí),以及什么情況訪問。有些是平安的,有些不是。使用SSL可以減少鑒權(quán)的本錢:你只需要一個(gè)簡(jiǎn)單的令牌〔token〕就可以鑒權(quán)了,而不是每次讓用戶對(duì)每次請(qǐng)求簽名。值得注意的是:不要讓非SSL的url訪問重定向到SSL的url。文檔f者存到需要登錄的地方都不太好〕。文檔應(yīng)該有展示請(qǐng)求和輸出的例子:或者以點(diǎn)擊鏈接的方式或者通過curl的方式〔請(qǐng)見openstack的文檔〕。如果有更新〔特別是公開的API〕,應(yīng)該及時(shí)更新文檔。文檔中應(yīng)該有關(guān)于何時(shí)棄用某個(gè)API的時(shí)間表以及詳情。使用郵件列表或者博客記錄是好方法。版本化在API上參加版本信息可以有效的防止用戶訪問已經(jīng)更新了的API,同時(shí)也能讓不同主要版本之間平穩(wěn)過渡。關(guān)于是否將版本信息放入url還是放入請(qǐng)求頭有過爭(zhēng)論: APIversionshouldbeincludedintheURLorinaheader.學(xué)術(shù)界說它應(yīng)該放strip使用的方法就很好:它的url里面有主版本信息,同時(shí)請(qǐng)求頭倆面有子版本信息。這樣在子版本變化過程中url的穩(wěn)定的。變化有時(shí)是不可防止的,關(guān)鍵是如何管理變化。完整的文檔和合理的時(shí)間表都會(huì)使得API使用者使用的更加輕松。結(jié)果過濾,排序,搜索:url最好越簡(jiǎn)短越好,和結(jié)果過濾,排序,搜索相關(guān)的功能都應(yīng)該通過參數(shù)實(shí)現(xiàn)(并且也很容易實(shí)現(xiàn))。返回結(jié)果:只返回那些open狀態(tài)的ticket–get/tickektsstate=open這里的state排序:和過濾一樣,一個(gè)好的排序參數(shù)應(yīng)該能夠描述排序規(guī)那么,而不業(yè)務(wù)相關(guān)。復(fù)雜的排序規(guī)那么應(yīng)該通過組合實(shí)現(xiàn):?GET/ticketssort=-priority-Retrievesalistofticketsindescendingorderofpriority?GET/ticketssort=-priority,created_at-Retrievesalistofticketsindescendingorderofpriority.Withinaspecificpriority,olderticketsareorderedfirst這里第二條查詢中,排序規(guī)那么有多個(gè)rule以逗號(hào)間隔組合而成。 搜索:有些時(shí)候簡(jiǎn)單的排序是不夠的。我們可以使用搜索技術(shù)〔ElasticSearch和Luceneurl的參數(shù)〕。?GET/ticketsq=return&state=open&sort=-priority,created_at-ioningthewordreturnIget/ticketsq=recently_closed->get/tickets/recently_closed.限制API返回值的域有時(shí)候API使用者不需要所有的結(jié)果,在進(jìn)展橫向限制的時(shí)候〔例如值返回API結(jié)果的前十項(xiàng)〕還應(yīng)該可以進(jìn)展縱向限制。并且這個(gè)功能能有效的提高網(wǎng)絡(luò)帶寬使用率和速度??梢允褂胒ields查詢參數(shù)來限制返回的域例如:/ticketsfields=id,subject,customer_name,updated_at&state=open&sort=-udatedat更新和創(chuàng)立操作應(yīng)該返回資源created_at,updated_at時(shí)間戳。為了防止用戶屢次的API調(diào)用〔為了進(jìn)展此次的更新操作〕,我們應(yīng)該會(huì)返回更新的資源〔updatedrepresentation.〕例如:在POST操作以后,返回201created狀態(tài)碼,并且包含一個(gè)指向新資源的url作為返回頭是否需要“HATEOAS“ 為此REST制定了HATEOAS來描述了和endpoint進(jìn)展交互的時(shí)候,行為應(yīng)該在metadata面進(jìn)展定義。〔譯注:作者這里認(rèn)為HATEOAS還不算成熟,我也不怎么理解這段就算了,讀者感興趣可以自己去原文查看〕只提供json作為返回格式XMLjsonXML各種編程語(yǔ)言解析。當(dāng)然XML有擴(kuò)展性的優(yōu)勢(shì),但是如果你只是將它來對(duì)內(nèi)部資源串行化,那么他的擴(kuò)展優(yōu)勢(shì)也發(fā)揮不出來。很多應(yīng)用〔youtube,twitter,box〕都已經(jīng)開場(chǎng)拋棄XML了,我也不想多費(fèi)口舌。給了google上的趨勢(shì)圖吧:當(dāng)然如果的你使用用戶里面企業(yè)用戶居多,那么可能需要支持XML。如果是這樣的話你還有另外一個(gè)問題:你的請(qǐng)求中的media類型是應(yīng)該和accept頭同步還是和url?為了方便〔browserexplorability〕,應(yīng)該是在url中(用戶只要自己拼url就好了)。如果這樣的話最好的方法是使用.xml或者.json的后綴。JAVASCRIPT的命名方法-也就是說駱駝命名法。如果你正在使用多種語(yǔ)言寫一個(gè)然這沒有什么理論的依據(jù)。有人說蛇不知道真假:///xpl/articleDetails.jsptp=&arnumber=5521745 默認(rèn)使用prettyprint格式,使用gzip只是使用空格的返回結(jié)果從瀏覽器上看總是覺得很惡心(一大坨有沒有?~)。當(dāng)然你可以提供url上的參數(shù)來控制使用“prettyprint〞,但是默認(rèn)開啟這個(gè)選項(xiàng)還是的-而不用將結(jié)果拷貝到其他什么軟件中在格式化-是想起來就很爽的事,不是么?下面是一個(gè)例子:curlsAPIgithub/users/veesahni>with-whitespace.txt$ruby-rjson-e'putsJSONJSON.parse(STDIN.read)'<with-whitespace.txt>without-whitespace.txt$gzip-cwith-whitespace.txt>with-whitespace.txt.gz$gzip-cwithout-whitespace.txt>without-whitespace.txt.gz輸出如下:?without-whitespace.txt-1252bytes?with-whitespace.txt-1369bytes?without-whitespace.txt.gz-496bytes?with-whitespace.txt.gz-509bytesItwitteramingAPIs 只在需要的時(shí)候使用“envelope〞很多API象下面這樣返回結(jié)果:1{2"data":{3"id":123,4"name":"John"5}6}理由很簡(jiǎn)單:這樣做可以很容易擴(kuò)展返回結(jié)果,你可以參加一些分頁(yè)信息,一些數(shù)據(jù)的元信息等-這對(duì)于那些不容易訪問到返回頭的API使用者來說確實(shí)有用,但是隨著“標(biāo)準(zhǔn)〞的開展〔cors和:///html/rfc5988#6都開場(chǎng)被參加到標(biāo)準(zhǔn)中了〕,我個(gè)人推薦不要那么做。何時(shí)使用envelope?有兩種情況是應(yīng)該使用envelope的。如果API使用者確實(shí)無法訪問返回頭,或者API需要支持穿插域請(qǐng)求〔通過jsonp〕。jsonp請(qǐng)求在請(qǐng)求的url中包含了一個(gè)callback函數(shù)參數(shù)。如果給出了這個(gè)參數(shù),那么API應(yīng)該返回200,并且把真正的狀態(tài)碼放到返回值里面〔包裝在信封里〕,例如:1callback_function({2status_code:200,3next_page:"s://..",4response:{5...actualJSONresponsebody...6}7})同樣為了支持無法方法返回頭的API使用者,可以允許envelope=true這樣的參在post,put,patch上使用json作為輸入 接下來考慮考慮API的輸入數(shù)據(jù)格式。很多的API使用url編碼格式:就像是url查詢參數(shù)的格式一樣:?jiǎn)渭兊逆I值對(duì)。這種方法簡(jiǎn)單有效,但是也有自己的問題:它沒有數(shù)據(jù)類型的概念。這使得程序不得不根據(jù)字符串解析出布爾和整數(shù),而且還沒有層次構(gòu)造–雖然有一些關(guān)于層次構(gòu)造信息的約定存在可是和本身就支持層次構(gòu)造的json比擬一下還是不很好用。當(dāng)然如果API本身就很簡(jiǎn)單,那么使用url格式的輸入沒什么問題。但對(duì)于復(fù)雜的API你應(yīng)該使用json?;蛘吒纱嘟y(tǒng)一使用json。注意使用json傳輸?shù)臅r(shí)候,要求請(qǐng)求頭里面參加:Content-Type:application/json.,否那么拋出415異?!瞮nsupportedmediatype〕。分頁(yè)分頁(yè)數(shù)據(jù)可以放到“信封〞里面,但隨著標(biāo)準(zhǔn)的改良,現(xiàn)在我推薦將分頁(yè)信息放到dertoolsietforghtmlrfcpagelinkheader的API應(yīng)該返回一系列組合好了的url而不是讓用戶自己再去拼。Link:<s://api.github/user/repos?page=3&per_page=100>;1rel="next",2<s://api.github/user/repos?page=50&per_page=100>;rel="last"自動(dòng)加載相關(guān)的資源 ticketembedcustomernameassigneduser對(duì)應(yīng)的API返回值如下:1{2"id":12,3"subject":"Ihaveaquestion!",4"summary":"Hi,",5"customer":{6"name":"Bob"7},8assigned_user:{9"id":42,10"name":"Jim",11}12}值得提醒的是,這個(gè)功能有時(shí)候會(huì)很復(fù)雜,并且可能導(dǎo)致N+1SELECT問題。重寫方法有的客戶端只能發(fā)出簡(jiǎn)單的GET和POST請(qǐng)求。為了照顧他們,我們可以重寫請(qǐng)求。這里沒有什么標(biāo)準(zhǔn),但是一個(gè)普遍的方式是承受X--Method-Override速度限制為了防止請(qǐng)求泛濫,給API設(shè)置速度限制很重要。為此RFC6585引入了狀態(tài)uests示標(biāo)準(zhǔn)上沒有說明,不過流行的方法是使用的返回頭。下面是幾個(gè)必須的返回頭〔依照twitter的命名規(guī)那么〕:?X-Rate-Limit-Limit:當(dāng)前時(shí)間段允許的并發(fā)請(qǐng)求數(shù)?X-Rate-Limit-Remaining:當(dāng)前時(shí)間段保存的請(qǐng)求數(shù)。?X-Rate-Limit-Reset:當(dāng)前時(shí)間段剩余秒數(shù) 為什么使用當(dāng)前時(shí)間段剩余秒數(shù)而不是時(shí)間戳?時(shí)間戳保存的信息很多,但是也包含了很多不必要的信息,用戶只需要知道還剩幾秒就可以再發(fā)請(qǐng)求了這樣也防止了clockskew問題。用RFC1123時(shí)間格式鑒權(quán)AuthenticationrestfulAPI是無狀態(tài)的也就是說用戶請(qǐng)求的鑒權(quán)和cookie以及session無關(guān),每求都應(yīng)該包含鑒權(quán)證明。通過使用ssl我們可以不用每次都提供用戶名和密碼:我們可以給用戶返回一個(gè)隨機(jī)產(chǎn)生的token。這樣可以極大的方便使用瀏覽器訪問API的用戶。這種方法適用于用戶可以首先通過一次用戶名-密碼的驗(yàn)證并得到token,并且可以拷貝返回的token到以后的請(qǐng)求中。如果不方便,可以使用OAuth2來進(jìn)展token的平安傳sonpcredential。這種情況下可以在查詢url中添加參數(shù):access_token。注意使用url參數(shù)的問題是:目前大局部的網(wǎng)絡(luò)效勞器都會(huì)講query參數(shù)保存到效勞器日志中,這可能會(huì)成為大的平安風(fēng)險(xiǎn)。注意上面說到的只是三種傳輸token的方法,實(shí)際傳輸?shù)膖oken可能是一樣的。緩存提供了自帶的緩存框架。你需要做的是在返回的時(shí)候參加一些返回頭信息,在 ETag:當(dāng)生成請(qǐng)求的時(shí)候,在頭里面參加ETag,其中包含請(qǐng)求的校驗(yàn)和和哈希值,這個(gè)值和在輸入變化的時(shí)候也應(yīng)該變化。如果輸入的請(qǐng)求包含IFNONEMATCH個(gè)ETag值,那么API應(yīng)該返回304notmodified狀不是常規(guī)的輸出結(jié)果。錯(cuò)處理就像html錯(cuò)誤頁(yè)面能夠顯示錯(cuò)誤信息一樣,API也應(yīng)該能返回可讀的錯(cuò)誤信息–它API者格

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論