RESTful Web Services

Programmable Web 及其分類

programmable web 是基于HTTP和XML技術(shù)。

  • 雖然HTML、JSON、純文本、二進(jìn)制也在使用,但采用較多的還是XML。
  • 基于HTTP

HTTP:信封里的文檔

HTTP是一中基于文檔的協(xié)議??蛻舳税盐臋n放在信封里,發(fā)給服務(wù)器;作為回應(yīng),服務(wù)器把響應(yīng)文檔放在信封里,發(fā)給客戶端。

HTTP對(duì)信封格式有嚴(yán)格的標(biāo)準(zhǔn),但它并不關(guān)心信封里的內(nèi)容。

HTTP請(qǐng)求的各個(gè)主要部分:

  • HTTP方法( HTTP method)
  • 路徑(path)
  • 請(qǐng)求報(bào)頭(request headers)
  • 實(shí)體主體(entity-body),也稱文檔(document)或表示(representation)

HTTP響應(yīng)代碼

  • 響應(yīng)報(bào)頭(response headers)
  • 實(shí)體

作用域信息

Web技術(shù)基礎(chǔ):HTTP應(yīng)用協(xié)議、URL命名標(biāo)準(zhǔn)、XML標(biāo)記語(yǔ)言

Web設(shè)計(jì)原則(REST):表示性狀態(tài)轉(zhuǎn)移(Representation State Transfer)

ROA:面向資源架構(gòu)(Resource-Oriented Architecture)

RESTful web services:REST式Web服務(wù)

HTTP方法(HTTP method):GET 獲取、HEAD、PUT 改寫、DELETE 刪除、POST

路徑(path):URI里主機(jī)名(hostname)后面的部分

請(qǐng)求報(bào)頭(request headers):是一組鍵值對(duì)(key-value pairs),起元數(shù)據(jù)的(metadata)作用。有8個(gè)報(bào)頭:Host、User-Agent、Accept、Content-Type

實(shí)體主體(entity-body):

相互競(jìng)爭(zhēng)的架構(gòu)

RPC式架構(gòu):方法信息和作用域信息都在信封(envelop)或報(bào)頭(headers)里。通常從客戶端收到一個(gè)充滿數(shù)據(jù)的信封,然后發(fā)回一個(gè)同樣充滿數(shù)據(jù)的信封。

REST式、面向資源的架構(gòu):REST架構(gòu)意味,方法信息(method information)都在HTTP方法里;ROA意味,作用域(scoping information)都在URI里。

WS-*

這些標(biāo)準(zhǔn)定義各種特定用途的SOAP報(bào)頭

WSDL(Web Service Description Language,Web 服務(wù)描述語(yǔ)言):用于描述SOAP Web服務(wù)的XML詞匯。

WADL(Web Application Description Language,Web 應(yīng)用描述語(yǔ)言):用于描述REST Web服務(wù)的XML詞匯。

面向資源的架構(gòu)

REST是一種設(shè)計(jì)原則。

REST式架構(gòu)-面向資源的架構(gòu)(Resource-Oriented Architecture,ROA)。

ROA是一種把實(shí)際問(wèn)題轉(zhuǎn)換成REST式Web服務(wù)的方法:它令URI、HTTP和XML具有和其他Web應(yīng)用一樣的工作方式。

ROA特性:

  • 可尋址性(addressability)
  • 無(wú)狀態(tài)性(statelessness)
  • 連通性(connectedness)
  • 統(tǒng)一接口(uniform interface)

URIs

  • URI應(yīng)具有描述性

  • URI跟資源的關(guān)系

  • 任何兩個(gè)資源都不可能是同一個(gè)

  • 兩個(gè)不同的資源在某一時(shí)刻可能指向同一個(gè)數(shù)據(jù)。

  • 可尋址性

  • 無(wú)狀態(tài)性

  • 每個(gè)HTTP請(qǐng)求都是完全孤立的。當(dāng)客戶端發(fā)出一個(gè)HTTP請(qǐng)求時(shí),請(qǐng)求里包含服務(wù)器實(shí)現(xiàn)該請(qǐng)求的全部信息。

  • 無(wú)狀態(tài)的特性,在負(fù)載均衡(load-balanced)服務(wù)器上分配無(wú)狀態(tài)的應(yīng)用將容易許多:請(qǐng)求之間沒(méi)有沒(méi)有相互依賴,要提升規(guī)模只需往負(fù)載均衡系統(tǒng)中添置更多的服務(wù)器即可。

  • 對(duì)無(wú)狀態(tài)的應(yīng)用緩存也比較容易。

  • 改變無(wú)狀態(tài)性,最常用的方法是利用HTTP會(huì)話(session)。當(dāng)用戶首次訪問(wèn)網(wǎng)站時(shí),會(huì)得到一個(gè)唯一的字符串,用以標(biāo)識(shí)在該網(wǎng)站上的會(huì)話。這個(gè)標(biāo)識(shí)是服務(wù)器端某個(gè)數(shù)據(jù)結(jié)構(gòu)中的key,通過(guò)這個(gè)key,可以在服務(wù)器端查到請(qǐng)求的狀態(tài)信息。

  • 狀態(tài)分為兩種:應(yīng)用狀態(tài)和資源狀態(tài),前者應(yīng)該保存在客戶端,后者應(yīng)該保存在服務(wù)端。

  • 表示

  • 資源是表示的來(lái)源,表示只是資源當(dāng)前狀態(tài)的一些數(shù)據(jù)。

  • 當(dāng)一個(gè)資源有多個(gè)表示時(shí),推薦為一個(gè)資源的多個(gè)表示設(shè)置不同的URI。例如:同一個(gè)文章不同語(yǔ)言的表示。

  • 通過(guò)設(shè)置Accept可以指定表示的首先格式。例如:Accept-Language。但盡量將更多的信息放在URI里。

  • 連接與連通性

  • 表示可以是系列化的數(shù)據(jù)結(jié)構(gòu)

  • 大多數(shù)的REST式服務(wù)里表示是超媒體,也就是說(shuō)文檔中不僅包含數(shù)據(jù)(data),還包含指向其他資源的鏈接。

  • 統(tǒng)一接口

HTTP四種基本方法:

  1. 獲取資源的一個(gè)表示 HTTP GET 。
  2. 創(chuàng)建一個(gè)新資源:向新的 URI 發(fā)送 HTTP PUT ,或向一個(gè) URI 發(fā)送 HTTP POST
  3. 修改已有的資源:向已有的 URI 發(fā)送 HTTP PUT
  4. 刪除已有資源: HTTP DELETE

其他:

  1. 獲取一個(gè)只包含元數(shù)據(jù)的表示: HTTP HEAD 。HEAD請(qǐng)求就是比GET請(qǐng)求少返回實(shí)體主體而已。
  2. 查看一個(gè)資源支持哪些HTTP方法: HTTP OPTIONS

POST與PUT

在一個(gè)REST式設(shè)計(jì)中,POST通常被用于創(chuàng)建從屬資源。

PUT與POST的區(qū)別在于:假如是客戶端負(fù)責(zé)決定新資源采用什么URI,就用PUT;假如服務(wù)器負(fù)責(zé)新資源采用什么URI,就用POST。

PUT和POST動(dòng)作

向新資源發(fā)PUT請(qǐng)求 向已有資源發(fā)PUT請(qǐng)求 POST
/weblogs N/A(資源已存在) 無(wú)效果 創(chuàng)建一個(gè)新的博客
/weblogs/myweblog 創(chuàng)建該博客 修改該博客的設(shè)置 往博客里添加一篇文章
/weblogs/myweblog/entries/ N/A(無(wú)法知道這個(gè)URI) 編輯該博客文章 為該博客文章添加評(píng)論

安全性和等冪性

GET和HEAD請(qǐng)求應(yīng)是安全的。

GET、HEAD、PUT、DELETE請(qǐng)求應(yīng)是等冪的。等冪性實(shí)踐要求是:不要允許客戶端對(duì)資源做相對(duì)的改動(dòng)。

設(shè)計(jì)只讀的面向資源服務(wù)

  1. 規(guī)劃數(shù)據(jù)集
  2. 把數(shù)據(jù)集劃分為資源
  3. 用URI為該資源命名
  4. 設(shè)計(jì)發(fā)給客戶端的表示
  5. 用超鏈接和表單把該資源與已有的資源聯(lián)系起來(lái)
  6. 考慮有哪些典型的事件經(jīng)過(guò)
  7. 考慮可能出現(xiàn)哪些錯(cuò)誤情況

把數(shù)據(jù)作為HTTP資源來(lái)發(fā)布:

  • 一個(gè)資源就是任何值得作為超鏈接的目標(biāo)事物。
  • 成為REST式網(wǎng)站,其資源的命名是有意義的,其資源的表示是整齊有序、且可以通過(guò)HTTP GET 來(lái)訪問(wèn)的。
  • 整齊有序的表示易于被解析和屏幕抓取。有意義的命名,令資源易于被程序引用。
  • 一個(gè)資源是某個(gè)事物,用面向?qū)ο蟮姆椒▉?lái)設(shè)計(jì)資源。
  • 一個(gè)資源只暴露一個(gè)統(tǒng)一的接口,最多支持六中HTTP方法,這些方法只允許創(chuàng)建(PUT或POST)、修改(PUT)、讀取(GET)和刪除(DELETE)這些最基本的操作。如果需要,可以通過(guò)重載POST來(lái)擴(kuò)展接口,把一個(gè)資源變成一個(gè)小型RPC式消息處理器

服務(wù)暴露的資源可分為三類:

  1. 為特別目的專門預(yù)定義的一次性資源。包括可用資源的最上層目錄。大多數(shù)服務(wù)幾乎不暴露一次性資源。例如:桶列表
  2. 服務(wù)暴露的每一個(gè)對(duì)象所對(duì)應(yīng)的資源。
  3. 代表在數(shù)據(jù)集上執(zhí)行的算法結(jié)果的資源

命名資源:URI設(shè)計(jì)有三條基本原則

  1. 用路徑變量來(lái)表達(dá)層次結(jié)構(gòu):/parent/child。
  2. 在路徑變量里加上標(biāo)點(diǎn)符號(hào),消除誤解:/parent/child1;child2。建議:當(dāng)作用域信息的次序有關(guān)緊要時(shí),用逗號(hào);否則用分號(hào)。
  3. 用查詢變量來(lái)表達(dá)算法的輸入:/search?q=jellyfish&start=20

總結(jié):
REST式Web服務(wù)通過(guò)資源來(lái)暴露數(shù)據(jù)(data)和算法(algorithms)。有關(guān)數(shù)據(jù)的資源常常構(gòu)成一個(gè)層次結(jié)構(gòu):由很少的資源開(kāi)始,然后逐漸擴(kuò)展為具有許多葉節(jié)點(diǎn)。

例如:S3桶列表(bucket list)包含各個(gè)桶,而各個(gè)桶又包含對(duì)象。
理解“把算法暴露為資源”,不要從動(dòng)作方面來(lái)考慮,而是從該動(dòng)作的結(jié)果方面來(lái)考慮。

設(shè)計(jì)可讀寫的面向資源的服務(wù)

  1. 規(guī)劃數(shù)據(jù)集
  2. 把數(shù)據(jù)集劃分為資源
  3. 用URI為該資源命名
  4. 暴露一個(gè)統(tǒng)一接口子集
  5. 設(shè)計(jì)來(lái)自客戶端的表示
  6. 設(shè)計(jì)發(fā)給客戶端的表示
  7. 用超鏈接和表單把資源與已有資源聯(lián)系起來(lái)
  8. 考慮有哪些典型的事件經(jīng)過(guò)
  9. 可慮可能出現(xiàn)哪些錯(cuò)誤情況

關(guān)鍵點(diǎn):

  • 認(rèn)證:把請(qǐng)求跟用戶關(guān)聯(lián)起來(lái)。

    • 認(rèn)證方案:
    1. HTTP基本驗(yàn)證(HTTP Basic)。
    2. HTTP摘要認(rèn)證(HTTP Digest)。
    3. WSSE認(rèn)證。
  • 授權(quán):確定一個(gè)給定用戶可以做哪些操作。

  • 保密性:數(shù)據(jù)要經(jīng)過(guò)一系列的計(jì)算機(jī)才能最終抵達(dá)客戶端,需要防止數(shù)據(jù)不被竊取。通常使用SSL對(duì)HTTP進(jìn)行加密。采用HTTPS可以防止其他計(jì)算機(jī)竊聽(tīng)客戶端與服務(wù)器之間的對(duì)話。

  • 表單編碼:

媒體類型(application/x-www-formurlencoded)。有時(shí)被稱為"CGI轉(zhuǎn)義"。

  • URI中使用URI-encoding編碼,例如:URI.escape
  • 表單中使用form-encoding編碼,例如:CGI::escape

REST和ROA最佳實(shí)踐

  • 安全性和等冪性:

  • GET和HEAD請(qǐng)求應(yīng)該是安全的。

  • PUT或DELETE請(qǐng)求應(yīng)該是等冪的。向一個(gè)URI發(fā)送多次PUT或DELETE請(qǐng)求,應(yīng)該和只做過(guò)一次請(qǐng)求的效果一樣。應(yīng)避免使用PUT請(qǐng)求對(duì)資源狀態(tài)作相對(duì)的改動(dòng)。

  • 新建資源:PUT vs POST

  • 只有當(dāng)客戶端能夠自己構(gòu)造出新的URI時(shí),才能夠使用PUT來(lái)創(chuàng)建資源。

  • 重載POST

  • 用于為Web瀏覽器這種不支持PUT和DELETE的客戶端模擬HTTP統(tǒng)一接口。

  • 繞過(guò)URI的最大長(zhǎng)度限制。

  • 需要考慮的問(wèn)題:

  • 異步操作

  • 批量操作

  • 事物

  • 認(rèn)證

  • 壓縮

  • 緩存

  • Cookies

服務(wù)的技術(shù)構(gòu)件表示格式:

  • XHTML(application/xhtml+xml)
  • Atom(application/atom+xml)發(fā)布協(xié)議
  • SVG(image/svg+xml)
  • 表單編碼的 關(guān)鍵字-值對(duì) (application/x-www-form-urlencoded)
  • JSON (application/json)
  • 特定框架的序列化格式(application/xml)

REST式服務(wù)框架

  • Ruby on Rails
  • Restlet:建立REST概念的Java類之間的映射
  • Django:方便用Python來(lái)開(kāi)發(fā)Web應(yīng)用和Web服務(wù)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,715評(píng)論 19 139
  • 一說(shuō)到REST,我想大家的第一反應(yīng)就是“啊,就是那種前后臺(tái)通信方式?!钡窃谝笤敿?xì)講述它所提出的各個(gè)約束,以及如...
    時(shí)待吾閱讀 3,608評(píng)論 0 19
  • RESTful web servicesare built to work best on the Web. Re...
    _東邪_閱讀 1,120評(píng)論 0 2
  • API定義規(guī)范 本規(guī)范設(shè)計(jì)基于如下使用場(chǎng)景: 請(qǐng)求頻率不是非常高:如果產(chǎn)品的使用周期內(nèi)請(qǐng)求頻率非常高,建議使用雙通...
    有涯逐無(wú)涯閱讀 2,952評(píng)論 0 6
  • 使用統(tǒng)一接口 HTTP是一種應(yīng)用層協(xié)議,然而,包括SOAP和一些Ajax Web框架在內(nèi)的不少技術(shù)都將HTTP作為...
    daoyidao閱讀 555評(píng)論 0 1

友情鏈接更多精彩內(nèi)容