RESTful架構,一種互聯網軟件架構。它結構清晰、符合標準、易於理解、擴展方便,因此正獲得愈來愈多網站的採用java
起源 REST這個詞,是Roy Thomas Fielding在他2000年的博士論文中提出的git
Fielding將他對互聯網軟件的架構原則,定名爲REST,即Representational State Transfer的縮寫。這個詞組的翻譯是"表現層狀態轉化",若是一個架構符合rest原則,咱們就稱它爲restful架構github
資源(resources)json
rest翻譯爲表現層狀態轉化,它沒有指名是誰的表現層,缺少主語,在這裏,咱們用資源當作主語,即爲資源的表現層狀態轉化。api
所謂資源,就是網絡上的一個實體,它能夠是一張圖片,一段文本。。。咱們能夠用一個url指向它,用戶經過url就能訪問到這個資源。數組
普及兩個概念 uri與url,uri(統一資源標識符 Uniform Resource Identifier),url(統一資源定位符 Uniform Resource Locator),其中url是uri的子集服務器
表現層(representation)restful
資源是一種信息實體,它能夠有多種外在表現,好比文本能夠以txt格式表現,也能夠用html,json,xml格式表現,咱們把資源具體呈現出的形式叫作它的表現層。網絡
uri指向資源,但不表明資源的形式,http頭部中的accept和content-type等表達了資源的形式
狀態轉化(state transfer)
訪問一個uri,就表明客戶和服務器發生了一個交互,這個過程會涉及到數據和狀態的變化。
互聯網通訊協議http協議,是無狀態的,不能記錄資源的各類狀態,資源的狀態保存在服務器端,若是要操做服務器上的資源,就要經過一些手段,讓服務器知道,從而讓服務器的資源發生狀態轉化,這個變化是創建在表現層之上的,就是表現層狀態轉化。
客戶端使用的手段,只能是http協議,http協議裏有不少操做方式的動詞好比get,post,put,delete,它們對應了四種基本操做,get用來獲取資源(查),post用來新建資源(增)或者修改資源(改),put用來更新資源(改),delete用來刪除資源(刪)。
綜上
restfull架構即爲
每一個url指向一種資源,客戶端和服務器之間傳遞資源的某種表現層,客戶經過4個http動詞,對服務器資源進行操做,實現服務器資源表現層狀態轉化
常見誤區
url中含有動詞,好比/users/update/1,其中update是動詞(手段),這個url就不知足restful架構,正確的寫法是/user/1,而後用put方式或post方式
url中帶有版本號,不一樣版本,能夠理解爲同一資源的不一樣表現形式,能夠把版本號放到http頭信息中,從url剔除
restful api設計
1、協議
api與用戶的通訊協議採用http協議
2、域名
儘可能將api部署到專用域名下,好比 http://api.test.com。若是api很少且比較簡單,不太會進一步擴展,也能夠放到主域名下,好比http://test.com/api/...
3、版本(version)
將版本號放到http頭信息中,也有說法說版本號放到url中更方便直接,github的是放在http頭信息裏的
4、路徑(endpoint)
路徑又稱「終點」(endpoint),表示api具體網址,在restful架構中,每一個網址表明一種資源(resource),因此網址中不能有動詞,好比說一個api提供動物園zoo信息,其中包括各類動物以及僱員信息,符合restful架構的url可以下設計
5、http動詞
對於資源的具體操做類型,由http動詞表示,經常使用的http動詞以下
兩個不經常使用http動詞
例子以下
6、信息過濾(filter)
若是資源數量過多,服務器很差一次性所有返回給用戶,api應該提供參數,過濾返回結果,好比指定篩選條件,排序,分頁,限制返回數量等
參數設計容許冗餘,即容許api路徑與url參數偶爾重複,好比 get /zoos/id/animals與 get /animals?zooId=id含義相同
7、狀態碼(status code)
服務器向用戶返回的狀態碼和提示信息,常見的列表如下
8、錯誤處理(error handling)
若是狀態碼是4xx,應該向用戶返回錯誤信息,通常來講,返回的信息中將error做爲鍵名,出錯信息做爲鍵值便可
9、返回結果
針對不一樣操做,服務器向用戶返回的結果應該符合如下規範
10、hypermedia api
restful api最好作到hypermedia,即返回結果中信息豐富一點,提供連接,連向其餘api方法,使得用戶不用去查詢文檔,也知道下一步應該作什麼。好比當用戶向api.test.com的根目錄發出請求時,獲得的文檔包含如下結果
{
"link":{ "rel": "collection http://api.test.com/zoos",
"href": "http://api/test.com",
"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就是這種設計,請求github的api會獲得一個全部可用api網址列表
{ "current_user_url": "https://api.github.com/user", "current_user_authorizations_html_url": "https://github.com/settings/connections/applications{/client_id}", "authorizations_url": "https://api.github.com/authorizations", "code_search_url": "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}", "commit_search_url": "https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}", "emails_url": "https://api.github.com/user/emails", "emojis_url": "https://api.github.com/emojis", "events_url": "https://api.github.com/events", "feeds_url": "https://api.github.com/feeds", "followers_url": "https://api.github.com/user/followers", "following_url": "https://api.github.com/user/following{/target}", "gists_url": "https://api.github.com/gists{/gist_id}", "hub_url": "https://api.github.com/hub", "issue_search_url": "https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}", "issues_url": "https://api.github.com/issues", "keys_url": "https://api.github.com/user/keys", "notifications_url": "https://api.github.com/notifications", "organization_repositories_url": "https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}", "organization_url": "https://api.github.com/orgs/{org}", "public_gists_url": "https://api.github.com/gists/public", "rate_limit_url": "https://api.github.com/rate_limit", "repository_url": "https://api.github.com/repos/{owner}/{repo}", "repository_search_url": "https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}", "current_user_repositories_url": "https://api.github.com/user/repos{?type,page,per_page,sort}", "starred_url": "https://api.github.com/user/starred{/owner}{/repo}", "starred_gists_url": "https://api.github.com/gists/starred", "team_url": "https://api.github.com/teams", "user_url": "https://api.github.com/users/{user}", "user_organizations_url": "https://api.github.com/user/orgs", "user_repositories_url": "https://api.github.com/users/{user}/repos{?type,page,per_page,sort}", "user_search_url": "https://api.github.com/search/users?q={query}{&page,per_page,sort,order}" }
從上面能夠看到,若是想獲取當前用戶的信息,應該去訪問api.github.com/user,會獲得以下返回結果
{ "message": "Requires authentication", "documentation_url": "https://developer.github.com/v3/users/#get-the-authenticated-user" }
返回結果給出了服務器的提示信息,以及相應文檔地址
11、其餘
api的身份認證可使用Oauth框架
服務器返回的數據格式,儘可能使用json,xml