restful規範

1、restful介紹

一、web服務交互

  網站提供的每一個web服務都須要先後端交互,先後端交互的實現方案,一般叫做:web服務交互方案。css

(1)目前主流的三種web服務交互方案

  1)REST(Representational State Transgfer)表述性狀態轉移html

  REST是Roy Thomas Fielding博士於2000年在他的博士論文裏提出來的。python

  REST相比SOAP更加簡潔,性能和開發效率也有突出的優點。git

  2)SOAP(Simple Object Access Protoco)簡單的對象訪問協議github

  SOAP服務則是以自己所定義的操做集,來訪問網絡上的資源。web

  SOAP也是基於XML的,可是它不僅限於HTTP協議的傳輸,包括TCP協議,UDP協議均可以傳輸。數據庫

  3)XML-RPC(XML Remote Procedure Call)基於XML的遠程過程調用django

  XML-RPC是經過XML將調用函數封裝,並使用HTTP協議做爲傳送機制。後來在新的功能不斷被引入下,這個標準慢慢演變成爲今日的SOAP協定。編程

二、理解REST

  REST與技術無關,表明的是一種軟件架構風格,REST是Representational State Transfer的簡稱,中文翻譯爲「表徵狀態轉移」。json

  這裏說的表徵性,其實就是資源。一般稱爲資源狀態轉移。

(1)什麼是資源

  什麼事物,只要有被引用的必要,它就是一個資源。資源能夠是一個實體,也能夠是抽象概念。

  實體資源很好理解,我的信息、手機號、視頻、圖片等等都是實實在在存在的實體。而兩我的的關係則是抽象的概念。

  在網絡中要引用資源,資源必定要有一個標識,在web中惟一標識就是URI

(2)什麼是URI和URL

  URI:統一資源標誌符(相似身份證號)。URL:統一資源定位符(相似家庭住址)。

  URI是給資源進行標識的,URL是描述資源地址的。

  經過這兩種方式均可以找到咱們的資源,其實URL能夠說是URI的子集,經過定位的方式實現的URI。

(3)統一資源接口

  得到URL後,能夠經過URL去訪問到資源,但對資源會有不少不一樣的操做(增刪改查)。以前的方式是分別設計一個新的URL來對數據進行操做。

  如今只須要一個URL,根據HTTP請求方式不一樣,對資源進行不一樣的操做,這就是統一資源接口

(4)資源的表述

  資源的表述其實就是資源的展示形式,客戶端和服務端傳輸的都是資源的表述,而不是資源自己。

  例如文本資源能夠採用html、xml、json等格式,圖片可使用PNG或JPG展示出來。

  那麼客戶端如何知道服務端提供哪一種表述形式呢?

  能夠經過HTTP內容協商,客戶端能夠經過Accept頭請求一種特定格式的表述,服務端則經過Content-Type告訴客戶端資源的表述形式。

  這些資源的表述呈如今頁面上,就是咱們說的資源狀態。

(5)狀態轉移

  看頁面的時候,從當前資源的表述(也能夠說狀態或者表現層)會跳轉到其餘的資源狀態。

  服務端經過超媒體告訴客戶端當前狀態有哪些後續狀態能夠進入。

  這些相似"下一頁"之類的連接起的就是這種推動狀態的做用——指引你如何從當前狀態進入下一個可能的狀態。 

(6)總結

  • REST與技術無關,表明的是一種軟件架構風格,REST是Representational State Transfer的簡稱,中文翻譯爲「表徵狀態轉移

  • REST從資源的角度類審視整個網絡,它將分佈在網絡中某個節點的資源經過URL進行標識,客戶端應用經過URL來獲取資源的表徵,得到這些表徵導致這些應用轉變狀態

  • 全部的數據,無論是經過網絡獲取的仍是操做(增刪改查)的數據,都是資源,將一切數據視爲資源是REST區別與其餘架構風格的最本質屬性

  • 對於REST這種面向資源的架構風格,有人提出一種全新的結構理念,即:面向資源架構(ROA:Resource Oriented Architecture)

三、什麼是restful

  若是一個架構符合REST的約束條件和原則,咱們就稱它爲RESTful架構。一種軟件的架構風格,設計風格,  爲客戶端和服務端的交互提供一組設計原則和約束條件。

  理解RESTful架構:http://www.ruanyifeng.com/blog/2011/09/restful.html

2、RESTful API設計

一、協議

  API與用戶的通訊協議,老是使用HTTPs協議

二、域名 

  • https://api.example.com                         儘可能將API部署在專用域名(會存在跨域問題)
  • https://example.org/api/                        API很簡單(若是肯定API很簡單,不會有進一步擴展,能夠考慮放在主域名下)

三、版本(Versioning)

  應該將API的版本號放入URL。另外一種作法是,將版本號放在HTTP頭信息中,但不如放入URL方便和直觀。Github採用這種作法。

  • URL,如:https://api.example.com/v1/
  • 請求頭

四、路徑(Endpoint)

路徑又稱"終點"(endpoint),表示API的具體網址。

在RESTful架構中,每一個網址表明一種資源(resource),因此網址中不能有動詞,只能有名詞,並且所用的名詞每每與數據庫的表格名對應。通常來講,數據庫中的表都是同種記錄的"集合"(collection),因此API中的名詞也應該使用複數。

視網絡上任何東西都是資源,均使用名詞表示(可複數)

  • https://api.example.com/v1/zoos
  • https://api.example.com/v1/animals
  • https://api.example.com/v1/employees

五、method(HTTP動詞)

對於資源的具體操做類型,由HTTP動詞表示。

經常使用的HTTP動詞有下面五個,後面是對應的SQL命令。

  • GET      :從服務器取出資源(一項或多項)                        --SELECT
  • POST    :在服務器新建一個資源                                       --CREATE
  • PUT      :在服務器更新資源(客戶端提供改變後的完整資源)--UPDATE
  • PATCH  :在服務器更新資源(客戶端提供改變的屬性)         --UPDATE
  • DELETE :從服務器刪除資源                                             --DELETE

還有兩個不經常使用的HTTP動詞:

  • HEAD     : 獲取資源的元數據。
  • OPTIONS: 獲取信息,關於資源的哪些屬性是客戶端能夠改變的。

示例:

  • GET /zoos:列出全部動物園
  • POST /zoos:新建一個動物園
  • GET /zoos/ID:獲取某個指定動物園的信息
  • PUT /zoos/ID:更新某個指定動物園的信息(提供該動物園的所有信息)
  • PATCH /zoos/ID:更新某個指定動物園的信息(提供該動物園的部分信息)
  • DELETE /zoos/ID:刪除某個動物園
  • GET /zoos/ID/animals:列出某個指定動物園的全部動物
  • DELETE /zoos/ID/animals/ID:刪除某個指定動物園的指定動物

六、過濾信息(Filtering)

若是記錄數量不少,服務器不可能都將它們返回給用戶。API應該提供參數,過濾返回結果。

經過在url上傳參的形式傳遞搜索條件

  • https://api.example.com/v1/zoos?limit=10:指定返回記錄的數量
  • https://api.example.com/v1/zoos?offset=10:指定返回記錄的開始位置
  • https://api.example.com/v1/zoos?page=2&per_page=100:指定第幾頁,以及每頁的記錄數
  • https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回結果按照哪一個屬性排序,以及排序順序
  • https://api.example.com/v1/zoos?animal_type_id=1:指定篩選條件

參數的設計容許存在冗餘,即容許API路徑和URL參數偶爾有重複。好比,GET /zoo/ID/animals 與 GET /animals?zoo_id=ID 的含義是相同的。

七、狀態碼(Status Codes)

服務器向用戶返回的狀態碼和提示信息,常見的有如下一些(方括號中是該狀態碼對應的HTTP動詞)。

200 OK - [GET]:服務器成功返回用戶請求的數據,該操做是冪等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:用戶新建或修改數據成功。
202 Accepted - [*]:表示一個請求已經進入後臺排隊(異步任務)
204 NO CONTENT - [DELETE]:用戶刪除數據成功。
400 INVALID REQUEST - [POST/PUT/PATCH]:用戶發出的請求有錯誤,服務器沒有進行新建或修改數據的操做,該操做是冪等的。
401 Unauthorized - [*]:表示用戶沒有權限(令牌、用戶名、密碼錯誤)。
403 Forbidden - [*] 表示用戶獲得受權(與401錯誤相對),可是訪問是被禁止的。
404 NOT FOUND - [*]:用戶發出的請求針對的是不存在的記錄,服務器沒有進行操做,該操做是冪等的。
406 Not Acceptable - [GET]:用戶請求的格式不可得(好比用戶請求JSON格式,可是隻有XML格式)。
410 Gone -[GET]:用戶請求的資源被永久刪除,且不會再獲得的。
422 Unprocesable entity - [POST/PUT/PATCH] 當建立一個對象時,發生一個驗證錯誤。
500 INTERNAL SERVER ERROR - [*]:服務器發生錯誤,用戶將沒法判斷髮出的請求是否成功。

更多看這裏:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

八、錯誤處理(Error handling)

狀態碼是4xx時,應向用戶返回錯誤信息,通常來講,返回的信息中將error做爲鍵名,出錯信息做爲鍵值便可。

{
    error: "Invalid API key"
}

九、返回結果

針對不一樣操做,服務器向用戶返回的結果應該符合如下規範。

GET /collection:返回資源對象的列表(數組)
GET /collection/resource:返回單個資源對象
POST /collection:返回新生成的資源對象
PUT /collection/resource:返回完整的資源對象
PATCH /collection/resource:返回完整的資源對象
DELETE /collection/resource:返回一個空文檔

十、Hypermedia API

RESTful API最好作到Hypermedia,即返回結果中提供連接,連向其餘API方法,使得用戶不查文檔,也知道下一步應該作什麼。

好比,當用戶向api.example.com的根目錄發出請求,會獲得這樣一個文檔。

{"link": {
  "rel":   "collection https://www.example.com/zoos",
  "href":  "https://api.example.com/zoos",
  "title": "List of zoos",
  "type":  "application/vnd.yourformat+json"
}}

上面代碼表示,文檔中有一個link屬性,用戶讀取這個屬性就知道下一步該調用什麼API了。rel表示這個API與當前網址的關係(collection關係,並給出該collection的網址),href表示API的路徑,title表示API的標題,type表示返回類型。

Hypermedia API的設計被稱爲HATEOAS。Github的API就是這種設計,訪問api.github.com會獲得一個全部可用API的網址列表。

3、resful 10大規範

  首先restful是一種軟件架構風格或者說是一種設計風格,並非標準,它只是提供了一組設計原則和約束條件,主要用於客戶端和服務器交互類的軟件。
  就像設計模式同樣,並非必定要遵循這些原則,而是基於這個風格設計的軟件能夠更簡潔,更有層次,咱們能夠根據開發的實際狀況,作相應的改變。它裏面提到了一些規範,例如:

一、儘可能使用HTTPS

  在url接口中推薦使用Https協議,讓網絡接口更加安全(Https是Http的安全版,即HTTP下加入 SSL層,HTTPS的安全基礎是SSL,所以加密的詳細內容就須要SSL(安全套接層協議));

二、url中能夠體現這是個API接口

  https://www.bootcss.com/v1/mycss

  https://v1.bootcss.com/mycss

三、url中還能夠體現版本號

  https://www.bootcss.com/v1/mycss

  https://v1.bootcss.com/mycss

  不一樣的版本能夠有不一樣的接口,使其更加簡潔,清晰。

四、面向對象編程

  restful 提倡面向資源編程,因此在url接口中儘可能要使用名詞,不要使用動詞。

五、url中體現過濾條件

  添加條件去篩選匹配:

  https://www.bootcss.com/v1/mycss?page=3

六、根據method不一樣,進行不一樣的操做

  能夠根據Http不一樣的method,進行不一樣的資源操做(5種方法:GET / POST / PUT / DELETE/ PATCH)

七、響應時應包含狀態碼

  能夠經過狀態碼直接判斷服務器的響應信息。

  1**   信息,服務器收到請求,須要請求者繼續執行操做

  2**  成功,操做被成功接收並處理

  3**  重定向,須要進一步的操做以完成請求

  4**  客戶端錯誤,請求包含語法錯誤或沒法完成請求

  5**  服務器錯誤,服務器在處理請求的過程當中發生了錯誤

八、返回值

  應該有返回值,並且格式爲統一的json格式。

  GET請求      返回查到全部或單條數據

  POST請求    返回新增的數據

  PUT請求       返回更新數據

  PATCH請求  局部更新  返回更新整條數據

九、返回錯誤信息

  返回值攜帶錯誤信息。

十、Hypermedia API(超連接)

  若是遇到須要跳轉的狀況,攜帶跳轉接口的URL。

  返回結果中要提供幫助連接,即API最好作到Hypermedia。

ret = {
    code: 1000,
    data:{
        id:1,
        name:'小強',
        depart_id:http://www.luffycity.com/api/v1/depart/8/
    }
}

4、rest framework框架的10大組件

一、路由

  • 能夠經過as_view傳參數,根據請求方式不一樣執行相應的方法
  • 能夠在url中設置一個結尾,相似於: .json

二、視圖

  • 幫助開發者提供了一些類,並在類中提供了多個方法以供咱們使用。

三、版本

  • 在url中設置version參數,用戶請求時候傳入參數。在request.version中獲取版本,根據版本不一樣 作不一樣處理

四、認證   

  • 寫一個類並註冊到認證類,在類的的authticate方法中編寫認證邏輯。
    • 認證成功(user,auth)
    • raise AuthticateFaild(....)
    • None

五、權限

  • 寫一個類並註冊到權限類,在類的的has_permission方法中編寫認證邏輯。
    • True
    • False

六、頻率限制

  • 寫一個類並註冊到頻率類,在類的的 allow_request/wait 方法中編寫認證邏輯。
  • allow_request
    • True
    • False 若是返回False,那麼就要執行wait

七、解析器

  • 根據ContentType請求頭,選擇不一樣解析器對 請求體中的數據進行解析。
    • POST /index/ http1.1.\r\nhost:11.11.11.11\r\nContent-Type:url-formendo....\r\n\r\nuser=alex&age=123
    • POST /index/ http1.1.\r\nhost:11.11.11.11\r\nContent-Type:application/json\r\n\r\n{....}

八、分頁

  • 對從數據庫中獲取到的數據進行分頁處理: SQL -> limit offset
    • 根據頁碼:http://www.luffycity.com/api/v1/student/?page=1&size=10
    • 根據索引:http://www.luffycity.com/api/v1/student/?offset=60&limit=10
    • 根據加密:http://www.luffycity.com/api/v1/student/?page=erd8
  • 問題:爲何頁碼越大速度越慢,以及如何解決?
  • 緣由:頁碼越大向後須要掃描的行數越多,由於每次都是從0開始掃描。
  • 解決:
    • 限制顯示的頁數
    • 記錄當前頁數據ID最大值和最小值,再次分頁時,根據ID現行篩選,而後再分頁。

九、序列化

  • 對queryset序列化以及對請求數據格式校驗。

十、渲染器

  • 根據URL中傳入的後綴,決定數據如何渲染到到頁面上。 

5、rest-framework參考博客

rest-framework框架的基本組件

Django Rest Framework

Django-rest-framework官網 

相關文章
相關標籤/搜索