如果你看到這里,你以前可能聽說過API 和REST,然后你就會想:“這些都是什么東西?”。也許你已經(jīng)了解過一些這方面的知識,但卻不知道從何入手。在這個教程中,我將會詮釋REST的基礎(chǔ)以及如何給應(yīng)用創(chuàng)建一個API(包括認(rèn)證授權(quán))。
API是Application Programming Interface(應(yīng)用程序界面)的縮寫,它是拿來描述一個類庫的特征或是如何去運用它。你個人收藏的類庫也許包含有可用功能的“API文檔”,那些必需的參數(shù)我們該怎么稱呼它們?諸如此類等等。
然而,如今很多人參考API文檔時,他們常常參考一種可能會通過網(wǎng)絡(luò)分享你的應(yīng)用數(shù)據(jù)HTTP API,例如,Twitter提供一個API能讓用戶在特定的格式下請求推文,以便用戶方便導(dǎo)入到自己的應(yīng)用程序中。這就是HTTP API的真正強(qiáng)大之處。它能夠從多個應(yīng)用程序中混搭數(shù)據(jù)到混合應(yīng)用程序中,或是創(chuàng)建一個能增強(qiáng)使用他人應(yīng)用體驗的應(yīng)用程序。
這樣說吧,比如說我們有一個可以允許我們查看(view),創(chuàng)建(create),編輯(edit)以及刪除(delete)部件的應(yīng)用程序。我們可以創(chuàng)建一個可以讓我們執(zhí)行這些功能的HTTP API:
當(dāng)人們開始去實現(xiàn)他們自己的API接口時,問題就出現(xiàn)了。竟然沒有一個標(biāo)準(zhǔn)的方法來命名URL,人們總是要參考API才得知它是如何運作的。一個API中可能命名一個URL為/view_widgets,但是另一個API可能就命名成/widgets/all.
不用擔(dān)心!REST幫你搞定這些混亂!
REST是Representational State Transfer的縮寫,它是由羅伊·菲爾?。≧oy Fielding)提出的,是用來描述創(chuàng)建HTTP API的標(biāo)準(zhǔn)方法的,他發(fā)現(xiàn)這四種常用的行為(查看(view),創(chuàng)建(create),編輯(edit)和刪除(delete))都可以直接映射到HTTP 中已實現(xiàn)的GET,POST,PUT和DELETE方法。
HTTP 中的8中不同的方法:
大多數(shù)情況下,當(dāng)你在使用你的瀏覽器的點點看看的時候,其實只用到HTTP的GET方法。GET方法是在你向因特網(wǎng)請求資源的時候才會用到的。當(dāng)你提交一個表單時,你就會經(jīng)常用到POST方法來回傳數(shù)據(jù)到網(wǎng)站上。至于其他的幾種方法,某些瀏覽器可能根本就沒有去完全實現(xiàn)它們。但是,如果是供我們使用的話,就沒什么問題。問題是我們有很多要選擇去幫助描述這四大行為的HTTP方法,我們將會用到那些已經(jīng)知道如何去使用這些不同的HTTP方法的客戶端類庫。
讓我們來看下幾個讓API表述性狀態(tài)轉(zhuǎn)移化的例子,就用我們之前說的那幾個部件來解釋:
你可能已經(jīng)注意的前面的幾個例子,REST URL使用著一套一致的命名方法。當(dāng)你跟API交互時,你幾乎經(jīng)常操作一些對象。在我們的例子中,我們講的是部件。在REST中,我們稱之為Resource。URL的第一部分經(jīng)常是這個資源的復(fù)數(shù)形式:
/widgets
當(dāng)我們參考收集的資源時(list all:列出所有 和add one:新增一個),這將會經(jīng)常用到。當(dāng)你用到一些特殊的資源的時候,你就會給URL增加一個id,這個URL在你想要“view”,“edit”和“delete”特殊資源的時候會被使用。
如果說,我們的部件有很多用戶使用,URL的結(jié)構(gòu)又將會是怎樣的呢?
嵌套資源在URL里是完全兼容的,但是超過兩層嵌套就不是很好的方法了。其實這根本不需要,因為你完全可以以ID的形式參考到那些嵌套資源,總比嵌套在父類中好。例如:
REST的另一重要部分就是為既定好請求的類型來響應(yīng)正確的狀態(tài)碼。如果你對HTTP狀態(tài)碼陌生,以下是一個簡易總結(jié)。當(dāng)你請求HTTP時,服務(wù)器會響應(yīng)一個狀態(tài)碼來判斷你的請求是否成功,然后客戶端應(yīng)如何繼續(xù)。以下是四種不同層次的狀態(tài)碼:
2xx = Success(成功)
3xx = Redirect(重定向)
4xx = User error(客戶端錯誤)
5xx = Server error(服務(wù)器端錯誤)
以下是一些最重要的狀態(tài)碼:
200 – OK (默認(rèn)的)
201 – Created(已創(chuàng)建)
202 – Accepted (已接受:常用語刪除請求)
400 –請求出錯(語法格式有誤或服務(wù)器無法理解此請求)
401 – 未授權(quán)(需要登錄)
404 – 找不到 (找不到所請求的文件或腳本)
405 – 不允許此方法(錯誤的 HTTP方法)
409 – 沖突 (IE嘗試以PUT請求創(chuàng)建相同的資源時)
當(dāng)你請求HTTP時,你可以請求你想要接收的格式。例如,請求一個網(wǎng)頁,你想以HTML的格式請求,或者如果你想要下載一張圖片,返回格式應(yīng)該是圖片的格式。然而,響應(yīng)請求格式是服務(wù)器的職責(zé)。
如今,JSON 已經(jīng)快速發(fā)展成為REST API選擇的格式,它有一個輕量級的、可讀性又很高的語法,以致其很容易操作。所以,當(dāng)使用我們API的用戶按他們想要的格式發(fā)出請求和指定JSON時。
要是用戶請求一個我們沒有實現(xiàn)的方法的格式時,我們又該怎么辦呢?你大可以拋出一些錯誤的類型。但我建議你將JSON格式作為你的標(biāo)準(zhǔn)響應(yīng)格式,因為這是開發(fā)者想要的格式。沒理由去支持其他的格式,除非你已經(jīng)有一個可支持的API。
事實上,創(chuàng)建一個REST API是超出此教程范圍的,因為它是有特定語言的。但我將以Ruby(一種為簡單快捷的面向?qū)ο缶幊潭鴦?chuàng)的腳本語言)的方式給出一個簡易例子,它使用一個叫Sinatra的類庫(不懂得可以自行百度)。
在一般的網(wǎng)頁應(yīng)用中,認(rèn)證操作是經(jīng)常要接收用戶名和密碼的,然后在session中保存用戶ID。用戶的瀏覽器就會保存會話中的ID到cookie中。當(dāng)用戶在網(wǎng)站上訪問需要認(rèn)證授權(quán)的頁面時,瀏覽器就會發(fā)送cookie,應(yīng)用程序就會查找seesion會話中的ID(如果它沒有失效的話),由于用戶的ID保存在seesion中,用戶就可以瀏覽頁面了。
用這個API,就可以使用seesion會話保存用戶記錄,但這畢竟不是最好的方法。有時候,用戶想直接訪問API,或是用戶想自己授權(quán)其他應(yīng)用程序去訪問這個API。
解決方法是在認(rèn)證的基礎(chǔ)上使用秘鑰。用戶輸入用戶名和密碼以登錄,應(yīng)用程序就以一個特殊秘鑰返回給用戶以備后續(xù)之需。這個秘鑰可以通入應(yīng)用程序,以至于如果用戶想要選擇拒絕應(yīng)用更進(jìn)一步的接入時,可以撤回這個秘鑰。
其實,網(wǎng)上已經(jīng)有一個做上面這件事的很流行的標(biāo)準(zhǔn)方式,叫做OAuth(開放授權(quán):是一個開放標(biāo)準(zhǔn),允許用戶讓第三方應(yīng)用訪問該用戶在某一網(wǎng)站上存儲的私密的資源(如照片,視頻,聯(lián)系人列表),與以往的授權(quán)方式不同之處是OAUTH的授權(quán)不會使第三方觸及到用戶的賬號信息(如用戶名與密碼),即第三方無需使用用戶的用戶名與密碼就可以申請獲得該用戶資源的授權(quán),因此OAUTH是安全的。),特別的,標(biāo)準(zhǔn)第二版的OAuth。網(wǎng)上有很多非常好的實現(xiàn)OAuth的資源,所以我才說那是超出此教程范圍的。如果你正在使用Ruby,這里有一些幫你解決大多數(shù)工作的很好的類庫,比如OmniAuth 。
花了那么多時間給你們講解這個教程,希望對你們有所幫助。