天天看點

初識RESTful

前言:兩個月沒寫部落格了,我真是太賤了哈哈。先簡單說下我這兩個月做了啥吧。8月26号從BIGO離職,回學校準備秋招。9月初時才發現已經錯過秋招内推時間,其實秋招内推拿offer是有較大機率的。9月才開始上牛客網,平時也沒怎麼刷題,是以9月投了很多大公司筆試沒過。

9月底,學校有個lianyou科技來開宣講會,官網也沒說明具體崗位,直接寫IT崗,尼瑪,這IT崗也太廣了吧。後來我還是去聽了,投了前端。一輪筆試,一輪群面+技術群面(面試官提問題,我們回答),最後一輪測試(考性格和智力)。後來去公司參觀了,公司還是有點國企背景的,一些硬福利真的很不錯。後來因為有更好的offer就不參考lianyou了。拒絕lianyou主要有兩個原因:

  1. 工資太低了,基本工資才6K
  2. 我實習主要做前端,自己更想搞後端,玩玩網站架構啥的(雖然這些現在不是很6)

10月放棄海投了,也上牛客網刷刷題,開始刷劍指offer。唉,别人已經刷完了,我才剛開始刷……

  10月中旬拿到深圳深信服的offer,測試開發崗。一輪技術面,50分鐘,聊的很廣,履歷項目的架構+Linux+python+網絡+現場出程式設計題寫代碼.....比較注重基礎,我現場反應能力還是不錯的。HR面(剛開始還不知道是hr,以為是技術面),就是聊天,我自我感覺超棒的,我綜合能力還是可以的。聊完,最後他伸手和我握手。

(内心)我去,不會吧,我挂了(春招有個面試官聊完還送我出門,然後就沒然後了……)!?好吧,沒戲了。最後,他說,老鄉。

我:天呐,真的嗎!!哈哈。後來發了offer,基本工資9K,一年15w. 9K在深圳算很一般的,不過比我第一個offer多了3K,也還不錯啦。

  10月底,拿了美圖的offer,地點在廈門,崗位是實驗室的資料平台開發,基本工資比深信服高。我打算下個月11月底先過去實習,争取在春節前實習兩個月哈哈。因為美圖是我想入職的公司,是以工資不明說了哈。深圳網際網路氛圍比廈門好,不過比起測試,我還是更喜歡美圖的開發崗位。

  so, 本渣渣的秋招就此結束啦。接下來一個月,我來寫一些django restful相關的部落格,目前也有在寫Linux,在伺服器這塊,一個月後我希望我能力應該是一個運維新人,Linux指令基本會awk,shell,grep,sed....也得會搭建一些服務django,ngnix....網絡的話,目前剛開始看TCP/IP詳解,争取實習前看完。資料庫這塊,之前看了mysql必知必會,最近也有看高性能mysql,可能會報個教育訓練班系統深入提高下資料庫這塊。

以上,就是我接下來的計劃!!

了解RESTful架構

越來越多的人開始意識到,網站即軟體,而且是一種新型的軟體。

這種"網際網路軟體"采用用戶端/伺服器模式,建立在分布式體系上,通過網際網路通信,具有高延時(high latency)、高并發等特點。

網站開發,完全可以采用軟體開發的模式。但是傳統上,軟體和網絡是兩個不同的領域,很少有交集;軟體開發主要針對單機環境,網絡則主要研究系統之間的通信。網際網路的興起,使得這兩個領域開始融合,現在我們必須考慮,如何開發在網際網路環境中使用的軟體。

初識RESTful

RESTful架構,就是目前最流行的一種網際網路軟體架構。它結構清晰、符合标準、易于了解、擴充友善,是以正得到越來越多網站的采用。

但是,到底什麼是RESTful架構,并不是一個容易說清楚的問題。下面,我就談談我了解的RESTful架構。

一、起源

REST這個詞,是Roy Thomas Fielding在他2000年的博士論文中提出的。

初識RESTful

Fielding是一個非常重要的人,他是HTTP協定(1.0版和1.1版)的主要設計者、Apache伺服器軟體的作者之一、Apache基金會的第一任主席。是以,他的這篇論文一經發表,就引起了關注,并且立即對網際網路開發産生了深遠的影響。

他這樣介紹論文的寫作目的:

"本文研究計算機科學兩大前沿----軟體和網絡----的交叉點。長期以來,軟體研究主要關注軟體設計的分類、設計方法的演化,很少客觀地評估不同的設計選擇對系統行為的影響。而相反地,網絡研究主要關注系統之間通信行為的細節、如何改進特定通信機制的表現,常常忽視了一個事實,那就是改變應用程式的互動風格比改變互動協定,對整體表現有更大的影響。我這篇文章的寫作目的,就是想在符合架構原理的前提下,了解和評估以網絡為基礎的應用軟體的架構設計,得到一個功能強、性能好、适宜通信的架構。"

(This dissertation explores a junction on the frontiers of two research disciplines in computer science: software and networking. Software research has long been concerned with the categorization of software designs and the development of design methodologies, but has rarely been able to objectively evaluate the impact of various design choices on system behavior. Networking research, in contrast, is focused on the details of generic communication behavior between systems and improving the performance of particular communication techniques, often ignoring the fact that changing the interaction style of an application can have more impact on performance than the communication protocols used for that interaction. My work is motivated by the desire to understand and evaluate the architectural design of network-based application software through principled use of architectural constraints, thereby obtaining the functional, performance, and social properties desired of an architecture. )

二、名稱

Fielding将他對網際網路軟體的架構原則,定名為REST,即Representational State Transfer的縮寫。我對這個詞組的翻譯是"表現層狀态轉化"。

如果一個架構符合REST原則,就稱它為RESTful架構。

要了解RESTful架構,最好的方法就是去了解Representational State Transfer這個詞組到底是什麼意思,它的每一個詞代表了什麼涵義。如果你把這個名稱搞懂了,也就不難體會REST是一種什麼樣的設計。

三、資源(Resources)

REST的名稱"表現層狀态轉化"中,省略了主語。"表現層"其實指的是"資源"(Resources)的"表現層"。

所謂"資源",就是網絡上的一個實體,或者說是網絡上的一個具體資訊。它可以是一段文本、一張圖檔、一首歌曲、一種服務,總之就是一個具體的實在。你可以用一個URI(統一資源定位符)指向它,每種資源對應一個特定的URI。要擷取這個資源,通路它的URI就可以,是以URI就成了每一個資源的位址或獨一無二的識别符。

所謂"上網",就是與網際網路上一系列的"資源"互動,調用它的URI。

四、表現層(Representation)

"資源"是一種資訊實體,它可以有多種外在表現形式。我們把"資源"具體呈現出來的形式,叫做它的"表現層"(Representation)。

比如,文本可以用txt格式表現,也可以用HTML格式、XML格式、JSON格式表現,甚至可以采用二進制格式;圖檔可以用JPG格式表現,也可以用PNG格式表現。

URI隻代表資源的實體,不代表它的形式。嚴格地說,有些網址最後的".html"字尾名是不必要的,因為這個字尾名表示格式,屬于"表現層"範疇,而URI應該隻代表"資源"的位置。它的具體表現形式,應該在HTTP請求的頭資訊中用Accept和Content-Type字段指定,這兩個字段才是對"表現層"的描述。

五、狀态轉化(State Transfer)

通路一個網站,就代表了用戶端和伺服器的一個互動過程。在這個過程中,勢必涉及到資料和狀态的變化。

網際網路通信協定HTTP協定,是一個無狀态協定。這意味着,所有的狀态都儲存在伺服器端。是以,如果用戶端想要操作伺服器,必須通過某種手段,讓伺服器端發生"狀态轉化"(State Transfer)。而這種轉化是建立在表現層之上的,是以就是"表現層狀态轉化"。

用戶端用到的手段,隻能是HTTP協定。具體來說,就是HTTP協定裡面,四個表示操作方式的動詞:GET、POST、PUT、DELETE。它們分别對應四種基本操作:GET用來擷取資源,POST用來建立資源(也可以用于更新資源),PUT用來更新資源,DELETE用來删除資源。

六、綜述

綜合上面的解釋,我們總結一下什麼是RESTful架構:

  (1)每一個URI代表一種資源;

  (2)用戶端和伺服器之間,傳遞這種資源的某種表現層;

  (3)用戶端通過四個HTTP動詞,對伺服器端資源進行操作,實作"表現層狀态轉化"。

七、誤區

RESTful架構有一些典型的設計誤區。

最常見的一種設計錯誤,就是URI包含動詞。因為"資源"表示一種實體,是以應該是名詞,URI不應該有動詞,動詞應該放在HTTP協定中。

舉例來說,某個URI是/posts/show/1,其中show是動詞,這個URI就設計錯了,正确的寫法應該是/posts/1,然後用GET方法表示show。

如果某些動作是HTTP動詞表示不了的,你就應該把動作做成一種資源。比如網上彙款,從賬戶1向賬戶2彙款500元,錯誤的URI是:

1

POST 

/accounts/1/transfer/500/to/2

正确的寫法是把動詞transfer改成名詞transaction,資源不能是動詞,但是可以是一種服務:

2

3

4

POST 

/transaction

HTTP

/1

.1

Host: 127.0.0.1

from=1&to=2&amount=500.00

另一個設計誤區,就是在URI中加入版本号:

http:

//www

.example.com

/app/1

.0

/foo

http:

//www

.example.com

/app/1

.1

/foo

http:

//www

.example.com

/app/2

.0

/foo

因為不同的版本,可以了解成同一種資源的不同表現形式,是以應該采用同一個URI。版本号可以在HTTP請求頭資訊的Accept字段中進行區分(參見Versioning REST Services):

Accept: vnd.example-com.foo+json; version=1.0

Accept: vnd.example-com.foo+json; version=1.1

Accept: vnd.example-com.foo+json; version=2.0

*注,雖說restfull規範建議版本号放在請求頭而不是url裡,但事實上為了使用友善,大多數開發者還是喜歡把版本号放在url上,這樣容易直覺區分

  

Restful API設計指南

接下來我将介紹RESTful API的設計細節,探讨如何設計一套合理、好用的API

初識RESTful

一、協定

API與使用者的通信協定,總是使用HTTPs協定。

二、域名

應該盡量将API部署在專用域名之下。

https:

//api

.example.com

如果确定API很簡單,不會有進一步擴充,可以考慮放在主域名下。  

https:

//example

.org

/api/

三、版本(Versioning)

應該将API的版本号放入URL。

https:

//api

.example.com

/v1/

另一種做法是,将版本号放在HTTP頭資訊中,但不如放入URL友善和直覺。Github采用這種做法。

四、路徑(Endpoint)

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

在RESTful架構中,每個網址代表一種資源(resource),是以網址中不能有動詞,隻能有名詞,而且所用的名詞往往與資料庫的表格名對應。一般來說,資料庫中的表都是同種記錄的"集合"(collection),是以API中的名詞也應該使用複數。

舉例來說,有一個API提供動物園(zoo)的資訊,還包括各種動物和雇員的資訊,則它的路徑應該設計成下面這樣。

https:

//api

.example.com

/v1/zoos

https:

//api

.example.com

/v1/animals

https:

//api

.example.com

/v1/employees

五、HTTP動詞

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

常用的HTTP動詞有下面五個(括号裡是對應的SQL指令)。

5

GET(SELECT):從伺服器取出資源(一項或多項)。

POST(CREATE):在伺服器建立一個資源。

PUT(UPDATE):在伺服器更新資源(用戶端提供改變後的完整資源)。

PATCH(UPDATE):在伺服器更新資源(用戶端提供改變的屬性)。

DELETE(DELETE):從伺服器删除資源。

還有兩個不常用的HTTP動詞。

HEAD:擷取資源的中繼資料。

OPTIONS:擷取資訊,關于資源的哪些屬性是用戶端可以改變的。

下面是一些例子。

6

7

8

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應該提供參數,過濾傳回結果。

下面是一些常見的參數。

?limit=10:指定傳回記錄的數量

?offset=10:指定傳回記錄的開始位置。

?page=2&per_page=100:指定第幾頁,以及每頁的記錄數。

?sortby=name&order=asc:指定傳回結果按照哪個屬性排序,以及排序順序。

?animal_type_id=1:指定篩選條件

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

七、狀态碼(Status Codes)

伺服器向使用者傳回的狀态碼和提示資訊,常見的有以下一些(方括号中是該狀态碼對應的HTTP動詞)。

9

10

11

12

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 - [*]:伺服器發生錯誤,使用者将無法判斷發出的請求是否成功。

狀态碼的完全清單參見這裡。

八、錯誤處理(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的網址清單。

{

"current_user_url"

"https://api.github.com/user"

,

"authorizations_url"

"https://api.github.com/authorizations"

,

/

/

...

}

從上面可以看到,如果想擷取目前使用者的資訊,應該去通路api.github.com/user,然後就得到了下面結果。

{

"message"

"Requires authentication"

,

"documentation_url"

"https://developer.github.com/v3"

}

上面代碼表示,伺服器給出了提示資訊,以及文檔的網址。  

十一、其他

(1)API的身份認證應該使用OAuth 2.0架構。

(2)伺服器傳回的資料格式,應該盡量使用JSON,避免使用XML。

十二、Django rest framework最佳實踐

http://www.cnblogs.com/alex3714/articles/7131523.html   

本文轉載自 http://www.ruanyifeng.com/blog/2014/05/restful_api.html   

作者:前程明亮

出處:http://www.cnblogs.com/0zcl

文章未标明轉載則為原創部落格。歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利.

1.非系統的學習也是在浪費時間

2.做一個會欣賞美,懂藝術,會藝術的技術人