歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> 創建 REST API 的最佳入門教程

創建 REST API 的最佳入門教程

日期:2017/2/28 13:56:28   编辑:Linux教程

如果你看到這裡,你以前可能聽說過API 和REST,然後你就會想:“這些都是什麼東西?”。也許你已經了解過一些這方面的知識,但卻不知道從何入手。在這個教程中,我將會诠釋REST的基礎以及如何給應用創建一個API(包括認證授權)。

什麼是API?

API是Application Programming Interface(應用程序界面)的縮寫,它是拿來描述一個類庫的特征或是如何去運用它。你個人收藏的類庫也許包含有可用功能的“API文檔”,那些必需的參數我們該怎麼稱呼它們?諸如此類等等。

然而,如今很多人參考API文檔時,他們常常參考一種可能會通過網絡分享你的應用數據HTTP API,例如,Twitter提供一個API能讓用戶在特定的格式下請求推文,以便用戶方便導入到自己的應用程序中。這就是HTTP API的真正強大之處。它能夠從多個應用程序中混搭數據到混合應用程序中,或是創建一個能增強使用他人應用體驗的應用程序。

這樣說吧,比如說我們有一個可以允許我們查看(view),創建(create),編輯(edit)以及刪除(delete)部件的應用程序。我們可以創建一個可以讓我們執行這些功能的HTTP API:

  1. http://example.com/view_widgets
  2. http://example.com/create_new_widget?name=Widgetizer
  3. http://example.com/update_widget?id=123&name=Foo
  4. http://example.com/delete_widget?id=123

當人們開始去實現他們自己的API接口時,問題就出現了。竟然沒有一個標准的方法來命名URL,人們總是要參考API才得知它是如何運作的。一個API中可能命名一個URL為/view_widgets,但是另一個API可能就命名成/widgets/all.

不用擔心!REST幫你搞定這些混亂!

什麼是REST?

REST是Representational State Transfer的縮寫,它是由羅伊·菲爾丁(Roy Fielding)提出的,是用來描述創建HTTP API的標准方法的,他發現這四種常用的行為(查看(view),創建(create),編輯(edit)和刪除(delete))都可以直接映射到HTTP 中已實現的GET,POST,PUT和DELETE方法。

HTTP 中的8中不同的方法:

  1. GET
  2. POST
  3. PUT
  4. DELETE
  5. OPTIONS
  6. HEAD
  7. TRACE
  8. CONNECT

大多數情況下,當你在使用你的浏覽器的點點看看的時候,其實只用到HTTP的GET方法。GET方法是在你向因特網請求資源的時候才會用到的。當你提交一個表單時,你就會經常用到POST方法來回傳數據到網站上。至於其他的幾種方法,某些浏覽器可能根本就沒有去完全實現它們。但是,如果是供我們使用的話,就沒什麼問題。問題是我們有很多要選擇去幫助描述這四大行為的HTTP方法,我們將會用到那些已經知道如何去使用這些不同的HTTP方法的客戶端類庫。

REST例子

讓我們來看下幾個讓API表述性狀態轉移的例子,就用我們之前說的那幾個部件來解釋:

如果我們想要查看所有部件,URL將是這個樣子:

  1. GET http://example.com/widgets

用POST方法新建一個用來發出請求數據的部件:

  1. POST http://example.com/widgets
  2. Data:
  3. name =Foobar

用GET方法查看一個簡單的部件,我們從指定的部件id中獲取:

  1. GET http://example.com/widgets/123

用PUT方法發送新數據來更新部件:

  1. PUT http://example.com/widgets/123
  2. Data:
  3. name =New name
  4. color = blue

用DELETE方法來刪除部件:

  1. DELETE http://example.com/widgets/123

解剖REST URL

你可能已經注意的前面的幾個例子,REST URL使用著一套一致的命名方法。當你跟API交互時,你幾乎經常操作一些對象。在我們的例子中,我們講的是部件。在REST中,我們稱之為Resource。URL的第一部分經常是這個資源的復數形式:

  1. /widgets

當我們參考收集的資源時(list all:列出所有 和add one:新增一個),這將會經常用到。當你用到一些特殊的資源的時候,你就會給URL增加一個id,這個URL在你想要“view”,“edit”和“delete”特殊資源的時候會被使用。

嵌套資源

如果說,我們的部件有很多用戶使用,URL的結構又將會是怎樣的呢?

列出所有用戶

  1. GET /widgets/123/users

新增一個用戶

  1. POST /widgets/123/users
  2. Data:
  3. name =Andrew

嵌套資源在URL裡是完全兼容的,但是超過兩層嵌套就不是很好的方法了。其實這根本不需要,因為你完全可以以ID的形式參考到那些嵌套資源,總比嵌套在父類中好。例如:

  1. /widgets/123/users/456/sports/789

這可以替換為:

  1. /users/456/sports/789

甚至可以替換成這樣:

  1. /sports/789

HTTP 狀態碼

REST的另一重要部分就是為既定好請求的類型來響應正確的狀態碼。如果你對HTTP狀態碼陌生,以下是一個簡易總結。當你請求HTTP時,服務器會響應一個狀態碼來判斷你的請求是否成功,然後客戶端應如何繼續。以下是四種不同層次的狀態碼:

  • 2xx = Success(成功)
  • 3xx = Redirect(重定向)
  • 4xx = User error(客戶端錯誤)
  • 5xx = Server error(服務器端錯誤)

以下是一些最重要的狀態碼:

請求成功的狀態碼:

  • 200 – OK (默認的)
  • 201 – Created(已創建)
  • 202 – Accepted (已接受:常用語刪除請求)

客戶端錯誤狀態碼:

  • 400 –請求出錯(語法格式有誤或服務器無法理解此請求)
  • 401 – 未授權(需要登錄)
  • 404 – 找不到 (找不到所請求的文件或腳本)
  • 405 – 不允許此方法(錯誤的 HTTP方法)
  • 409 – 沖突 (IE嘗試以PUT請求創建相同的資源時)

API響應格式

當你請求HTTP時,你可以請求你想要接收的格式。例如,請求一個網頁,你想以HTML的格式請求,或者如果你想要下載一張圖片,返回格式應該是圖片的格式。然而,響應請求格式是服務器的職責。

如今,JSON 已經快速發展成為REST API選擇的格式,它有一個輕量級的、可讀性又很高的語法,以致其很容易操作。所以,當使用我們API的用戶按他們想要的格式發出請求和指定JSON時。

  1. GET /widgets
  2. Accept: application/json

我們的API將會以JSON的格式返回一批部件:

  1. [
  2. {
  3. id:123,
  4. name:'Simple Widget'
  5. },
  6. {
  7. id:456,
  8. name:'My other widget'
  9. }
  10. ]

要是用戶請求一個我們沒有實現的方法的格式時,我們又該怎麼辦呢?你大可以拋出一些錯誤的類型。但我建議你將JSON格式作為你的標准響應格式,因為這是開發者想要的格式。沒理由去支持其他的格式,除非你已經有一個可支持的API。

創建一個REST API

事實上,創建一個REST API是超出此教程范圍的,因為它是有特定語言的。但我將以Ruby(一種為簡單快捷的面向對象編程而創的腳本語言)的方式給出一個簡易例子,它使用一個叫Sinatra的類庫(不懂得可以自行百度)。

  1. require'sinatra'
  2. require'JSON'
  3. require'widget'#our imaginary widget model
  4. #list all
  5. get'/widgets'do
  6. Widget.all.to_json
  7. end
  8. # view one
  9. get'/widgets/:id'do
  10. widget=Widget.find(params[:id])
  11. returnstatus404ifwidget.nil?
  12. widget.to_json
  13. end
  14. # create
  15. post'/widgets'do
  16. widget=Widget.new(params['widget'])
  17. widget.save
  18. status201
  19. end
  20. # update
  21. put'/widgets/:id'do
  22. widget=Widget.find(params[:id])
  23. returnstatus404ifwidget.nil?
  24. widget.update(params[:widget])
  25. widget.save
  26. status202
  27. end
  28. delete'/widgets/:id'do
  29. widget=Widget.find(params[:id])
  30. returnstatus404ifwidget.nil?
  31. widget.delete
  32. status202
  33. end

API授權認證

在一般的網頁應用中,認證操作是經常要接收用戶名和密碼的,然後在session中保存用戶ID。用戶的浏覽器就會保存會話中的ID到cookie中。當用戶在網站上訪問需要認證授權的頁面時,浏覽器就會發送cookie,應用程序就會查找seesion會話中的ID(如果它沒有失效的話),由於用戶的ID保存在seesion中,用戶就可以浏覽頁面了。

用這個API,就可以使用seesion會話保存用戶記錄,但這畢竟不是最好的方法。有時候,用戶想直接訪問API,或是用戶想自己授權其他應用程序去訪問這個API。

解決方法是在認證的基礎上使用秘鑰。用戶輸入用戶名和密碼以登錄,應用程序就以一個特殊秘鑰返回給用戶以備後續之需。這個秘鑰可以通入應用程序,以至於如果用戶想要選擇拒絕應用更進一步的接入時,可以撤回這個秘鑰。

其實,網上已經有一個做上面這件事的很流行的標准方式,叫做OAuth(開放授權:是一個開放標准,允許用戶讓第三方應用訪問該用戶在某一網站上存儲的私密的資源(如照片,視頻,聯系人列表),與以往的授權方式不同之處是OAUTH的授權不會使第三方觸及到用戶的帳號信息(如用戶名與密碼),即第三方無需使用用戶的用戶名與密碼就可以申請獲得該用戶資源的授權,因此OAUTH是安全的。),特別的,標准第二版的OAuth。網上有很多非常好的實現OAuth的資源,所以我才說那是超出此教程范圍的。如果你正在使用Ruby,這裡有一些幫你解決大多數工作的很好的類庫,比如OmniAuth 。

花了那麼多時間給你們講解這個教程,希望對你們有所幫助。

Copyright © Linux教程網 All Rights Reserved