首先要說的是,這是來自stackoverflow的一個高票答案(提問的問題就是我這篇翻譯的標題),其次就是這個回答有點偏離正題,可是不影響咱們對RESTful的理解,最起碼讓我走出了一個誤區,這裏強烈推薦另一篇文章:我是咋向我老婆解釋REST滴,看的茅塞頓開有沒有!!html
原文連接web
REST是web世界的基本架構原則,關於web最神奇的事就是:明明以前客戶端對服務器以及服務器資源一無所知,客戶端(瀏覽器)和服務器卻可使用複雜的方式來相互做用 。而關鍵的約束就是服務器以及瀏覽器客戶端都在使用媒介上達成一致,而在web裏咱們都知道這個媒介就是HTML。數據庫
因此,堅持使用REST原則的API是不要求客戶端了解該API的任何結構滴!相反,服務器會提供全部客戶端與服務器交互所須要的消息,一個HTML的表單就是很好的例子:服務器指定資源的位置,以及須要的字段信息。瀏覽器不須要提早知道去哪裏提交信息而且瀏覽器也不知道提交什麼信息,這兩種表單信息都是徹底由服務器提供的(這種原則就被稱爲HATEOAS)(譯者注:HATEOAS是Hypermedia As The Engine Of Application State的縮寫)。json
因此這貨是怎麼用在HTTP,咱們又怎麼在實踐中使用呢?Https是面向動做(verb)和資源(resource)的,我以爲幾乎全部的人都知道常常用的兩個動做就是GET和POST,可是實際上HTTP標準還定義了其餘的一些動做好比DELECT和PUT,這些動做根據服務器指令規定也會做用在資源上。api
好比,如今咱們想象有一個web服務在管理着一個數據庫,咱們的服務是基於自定義的JSON,所以咱們定義一個application/json+userdb((這裏也許還有application/xml+userdb 以及application/whatever+userdb - 許多的媒體類型都是支持的),服務器以及客戶端的程序被寫成了都能理解這種格式,可是相互之間沒有任何聯繫,正如Roy Fielding指出的:瀏覽器
一個REST API應該把全部的精力都放在定義被用在表示資源和驅動應用狀態的媒體類型(media type)上邊,或者是爲已經存在的標準媒體類型定義擴展的關係名以及超文本標記服務器
一個對基本資源「/」的請求可能返回一些下邊這樣的:restful
request:架構
GET / Accept: application/json+userdb
response:app
200 OK Content-Type: application/json+userdb { "version": "1.0", "links": [ { "href": "/user", "rel": "list", "method": "GET" }, { "href": "/user", "rel": "create", "method": "POST" } ] }
根據media的描述咱們能夠從部分被稱爲連接的部分上獲得一些關於資源的信息,這被稱爲超媒體連接。在這種狀況下,咱們被告知了能夠經過造另一個連接「/user」來找尋一個user列表:
request:
GET /user Accept: application/json+userdb
response:
200 OK Content-Type: application/json+userdb { "users": [ { "id": 1, "name": "Emil", "country: "Sweden", "links": [ { "href": "/user/1", "rel": "self", "method": "GET" }, { "href": "/user/1", "rel": "edit", "method": "PUT" }, { "href": "/user/1", "rel": "delete", "method": "DELETE" } ] }, { "id": 2, "name": "Adam", "country: "Scotland", "links": [ { "href": "/user/2", "rel": "self", "method": "GET" }, { "href": "/user/2", "rel": "edit", "method": "PUT" }, { "href": "/user/2", "rel": "delete", "method": "DELETE" } ] } ], "links": [ { "href": "/user", "rel": "create", "method": "POST" } ] }
咱們從這個連接裏又被告知了許多的東西,好比,咱們知道咱們能夠經過POSTing這個「/user」來建立一個user:
request:
POST /user Accept: application/json+userdb Content-Type: application/json+userdb { "name": "Karl", "country": "Austria" }POST /user Accept: application/json+userdb Content-Type: application/json+userdb { "name": "Karl", "country": "Austria" }
response:
201 Created Content-Type: application/json+userdb { "user": { "id": 3, "name": "Karl", "country": "Austria", "links": [ { "href": "/user/3", "rel": "self", "method": "GET" }, { "href": "/user/3", "rel": "edit", "method": "PUT" }, { "href": "/user/3", "rel": "delete", "method": "DELETE" } ] }, "links": { "href": "/user", "rel": "list", "method": "GET" } }
咱們一樣知道了能夠改變現有的數據:
request:
PUT /user/1 Accept: application/json+userdb Content-Type: application/json+userdb { "name": "Emil", "country": "Bhutan" }
response:
200 OK Content-Type: application/json+userdb { "user": { "id": 1, "name": "Emil", "country": "Bhutan", "links": [ { "href": "/user/1", "rel": "self", "method": "GET" }, { "href": "/user/1", "rel": "edit", "method": "PUT" }, { "href": "/user/1", "rel": "delete", "method": "DELETE" } ] }, "links": { "href": "/user", "rel": "list", "method": "GET" } }
注意咱們使用的不一樣的動詞(GET, PUT, POST, DELETE etc.)來操縱資源,固然咱們假設客戶端的部分只有咱們的media定義
深刻閱讀:
Martin Fowler's thoughts
Paypalde API | has hypermedia controls
(這篇文章由於其主觀性而備受批評,而大多數的批評都是得當的,我以前的回答彷佛更偏向與Rest是如何在頭幾年實施的而不是如今你們看到的,我已經修改了答案使之更符合題目)編輯於1月18號