在移動互聯網的大潮下,隨着docker等技術的興起,『微服務』的概念也愈來愈被你們接受並應用於實踐,日益增多的web service逐漸統一於RESTful 架構風格,若是開發者對RESTful 架構風格不甚瞭解,則開發出的所謂RESTful API總會貌合神離,不夠規範。python
本文是我對RESTful 架構風格的一些理解,和你們分享一下,若是有問題,歡迎討論。web
RESTful架構風格最初由Roy T. Fielding(HTTP/1.1協議專家組負責人)在其2000年的博士學位論文中提出。HTTP就是該架構風格的一個典型應用。從其誕生之日開始,它就因其可擴展性和簡單性受到愈來愈多的架構師和開發者們的青睞。一方面,隨着雲計算和移動計算的興起,許多企業願意在互聯網上共享本身的數據、功能;另外一方面,在企業中,RESTful API(也稱RESTful Web服務)也逐漸超越SOAP成爲實現SOA的重要手段之一。時至今日,RESTful架構風格已成爲企業級服務的標配。docker
REST即Representational State Transfer的縮寫,可譯爲"表現層狀態轉化」。REST最大的幾個特色爲:資源、統一接口、URI和無狀態。數據庫
所謂"資源",就是網絡上的一個實體,或者說是網絡上的一個具體信息。它能夠是一段文本、一張圖片、一首歌曲、一種服務,總之就是一個具體的實在。資源總要經過某種載體反應其內容,文本能夠用txt格式表現,也能夠用HTML格式、XML格式表現,甚至能夠採用二進制格式;圖片能夠用JPG格式表現,也能夠用PNG格式表現;JSON是如今最經常使用的資源表示格式。json
結合個人開發實踐,我對資源和數據理解以下:安全
資源是以json(或其餘Representation)爲載體的、面向用戶的一組數據集,資源對信息的表達傾向於概念模型中的數據:服務器
相對而言,數據(尤爲是數據庫)是一種更加抽象的、對計算機更高效和友好的數據表現形式,更多的存在於邏輯模型中restful
資源和數據關係以下:cookie
RESTful架構風格規定,數據的元操做,即CRUD(create, read, update和delete,即數據的增刪查改)操做,分別對應於HTTP方法:GET用來獲取資源,POST用來新建資源(也能夠用於更新資源),PUT用來更新資源,DELETE用來刪除資源,這樣就統一了數據操做的接口,僅經過HTTP方法,就能夠完成對數據的全部增刪查改工做。網絡
即:
能夠用一個URI(統一資源定位符)指向資源,即每一個URI都對應一個特定的資源。要獲取這個資源,訪問它的URI就能夠,所以URI就成了每個資源的地址或識別符。
通常的,每一個資源至少有一個URI與之對應,最典型的URI即URL。
所謂無狀態的,即全部的資源,均可以經過URI定位,並且這個定位與其餘資源無關,也不會由於其餘資源的變化而改變。有狀態和無狀態的區別,舉個簡單的例子說明一下。如查詢員工的工資,若是查詢工資是須要登陸系統,進入查詢工資的頁面,執行相關操做後,獲取工資的多少,則這種狀況是有狀態
的,由於查詢工資的每一步操做都依賴於前一步操做,只要前置操做不成功,後續操做就沒法執行;若是輸入一個url便可獲得指定員工的工資,則這種狀況是無狀態
的,由於獲取工資不依賴於其餘資源或狀態,且這種狀況下,員工工資是一個資源,由一個url與之對應,能夠經過HTTP中的GET
方法獲得資源,這是典型的RESTful風格。
ROA
即Resource Oriented Architecture,RESTful 架構風格的服務是圍繞資源
展開的,是典型的ROA架構(雖然「A」和「架構」存在重複,但說無妨),雖然ROA與SOA並不衝突,甚至把ROA看作SOA的一種也何嘗不可,但因爲RPC也是SOA,比較久遠一點點論文、博客或圖書也常把SOA與RPC混在一塊兒討論,所以,RESTful 架構風格的服務一般被稱之爲ROA架構,不多說起SOA架構,以便更加顯式的與RPC區分。
RPC風格曾是Web Service的主流,最初是基於XML-RPC協議(一個遠程過程調用(remote procedure call,RPC)的分佈式計算協議),後來漸漸被SOAP協議(簡單對象訪問協議(Simple Object Access Protocol))取代;RPC風格的服務,不只能夠用HTTP
,還能夠用TCP
或其餘通訊協議。但RPC風格的服務,受開發服務採用語言的束縛比較大,如.NET框架中,開發web service的傳統方式是使用WCF,基於WCF開發的服務即RPC風格的服務,使用該服務的客戶端一般要用C#來實現,若是使用python或其餘語言,很難實現能夠直接與服務通訊客戶端;進入移動互聯網時代後,RPC風格的服務很難在移動終端使用,而RESTful風格的服務,因爲能夠直接以json
或xml
爲載體承載數據,以HTTP方法爲統一接口完成數據操做,客戶端的開發不依賴於服務實現的技術,移動終端也能夠輕鬆使用服務,這也加重了REST取代RPC成爲web service的主導。
RPC與RESTful的區別以下面兩個圖所示:
一般開發者作服務相關的客戶端開發時,使用的所謂RESTful服務,基本可分爲本真REST
和hybrid風格
兩類。本真REST
即我上文闡述的RESTful架構風格,具備上述的4個特色,是真正意義上的RESTful風格;而hybrid風格
,只是借鑑了RESTful的一些優勢,具備一部分RESTful的特色,但對外依然宣稱是RESTful風格的服務。(竊覺得,正是因爲hybrid風格服務混淆了RESTful的概念,纔在RESTful架構風格提出了本真REST的概念,覺得了劃分界限 :P)
hybrid風格的最主流的用法是,使用GET
方法獲取資源,用POST
方法實現資源的建立、修改和刪除。hybrid風格之因此存在,據我瞭解有兩種來源:一種狀況是由於,某些開發者並無真正理解何爲RESTful架構風格,致使開發的服務貌合神離;而主流的緣由是因爲歷史包袱 —— 服務原本是RPC風格的,因爲上文提到的RPC的劣勢及RESTful的優點,開發者在RPC風格的服務上又包裝了一層RESTful的外殼,一般這層外殼只爲獲取資源服務,所以會按RESTful風格實現GET
方法,若是客戶端提出一些簡單的建立、修改或刪除數據的需求,則經過HTTP協議中最經常使用的POST
方法實現相應功能。
所以,開發RESTful 服務,若是沒有歷史包袱,不建議使用hybrid風格。
因爲RESTful風格的服務是無狀態的,認證機制尤其重要。例如上文提到的員工工資,這應該是一個隱私資源,只有員工本人或其餘少數有權限的人有資格看到,若是不經過權限認證機制對資源作一層限制,那麼全部資源都以公開方式暴露出來,這是不合理的,也是很危險的。
認證機制解決的問題是,肯定訪問資源的用戶是誰;權限機制解決的問題是,肯定用戶是否被許可以使用、修改、刪除或建立資源。權限機制一般與服務的業務邏輯綁定,所以權限機制須要在每一個系統內部定製,而認證機制基本上是通用的,經常使用的認證機制包括 session auth
(即經過用戶名密碼登陸),basic auth
,token auth
和OAuth
,服務開發中經常使用的認證機制爲後三者。
HTTP Basic authentication (BA) implementation is the simplest technique for enforcing access controls to web resources because it doesn't require cookies, session identifier and login pages. Rather, HTTP Basic authentication uses static, standard fields in the HTTP header which means that no handshakes have to be done in anticipation.
簡言之,Basic Auth是配合RESTful API 使用的最簡單的認證方式,只需提供用戶名密碼便可,但因爲有把用戶名密碼暴露給第三方客戶端的風險,在生產環境下被使用的愈來愈少。所以,在開發對外開放的RESTful API時,儘可能避免採用Basic Auth
Token Auth並不經常使用,它與Basic Auth的區別是,不將用戶名和密碼發送給服務器作用戶認證,而是向服務器發送一個事先在服務器端生成的token來作認證。所以Token Auth要求服務器端要具有一套完整的Token建立和管理機制,該機制的實現會增長大量且非必須的服務器端開發工做,也不見得這套機制足夠安全和通用,所以Token Auth用的並很少。
本文不在展開介紹Token Auth,我我的對這套機制也瞭解有限,有興趣瞭解這套機制的同窗不妨從Stack Overflow上的這篇討論入手。
OAuth is an open standard for authorization. OAuth provides client applications a 'secure delegated access' to server resources on behalf of a resource owner. It specifies a process for resource owners to authorize third-party access to their server resources without sharing their credentials. Designed specifically to work with Hypertext Transfer Protocol (HTTP), OAuth essentially allows access tokens to be issued to third-party clients by an authorization server, with the approval of the resource owner. The client then uses the access token to access the protected resources hosted by the resource server. OAuth is commonly used as a way for Internet users to log into third party websites using their Microsoft, Google, Facebook or Twitter accounts without exposing their password.
OAuth is a service that is complementary to and distinct from OpenID. OAuth is also distinct from OATH, which is a reference architecture for authentication, not a standard for authorization. However, OAuth is directly related to OpenID Connect (OIDC) since OIDC is an authentication layer built on top of OAuth 2.0.
OAuth(開放受權)是一個開放的受權標準,容許用戶讓第三方應用訪問該用戶在某一web服務上存儲的私密的資源(如照片,視頻,聯繫人列表),而無需將用戶名和密碼提供給第三方應用。
OAuth容許用戶提供一個令牌,而不是用戶名和密碼來訪問他們存放在特定服務提供者的數據。每個令牌受權一個特定的第三方系統(例如,視頻編輯網站)在特定的時段(例如,接下來的2小時內)內訪問特定的資源(例如僅僅是某一相冊中的視頻)。這樣,OAuth讓用戶能夠受權第三方網站訪問他們存儲在另外服務提供者的某些特定信息,而非全部內容。
正是因爲OAUTH的嚴謹性和安全性,如今OAUTH已成爲RESTful架構風格中最經常使用的認證機制,和RESTful架構風格一塊兒,成爲企業級服務的標配。
目前OAuth已經從OAuth1.0發展到OAuth2.0,但這兩者並不是平滑過渡升級,OAuth2.0在保證安全性的前提下大大減小了客戶端開發的複雜性,所以,Gevin建議在實戰應用中採用OAuth2.0認證機制。
如今網上關於OAuth的資料很是豐富,也有大量開源的第三方庫實現了OAuth機制,不熟悉OAuth的同窗從OAuth官網入手便可。