1.5 RESTful

REST(REpresentational State Transfer)是Dr. Roy Thomas Fielding在2000年於他的博士論文中提出來的一種互聯網軟體架構風格, 目的是便於不同軟體/程序在網路中互相傳遞訊息.

目前在三種主流的webservice實作方案中, 由於REST相較於SOAP與XML-RPC更加地簡潔, 越來越多的webservice開始採用RESTful設計與實作.

REST的要點與標準:

前面強調了, REST是設計的一種風格, 不是標準, 其通常會基於使用HTTP, URI, XML以及HTML這些現有廣泛流行的協議與標準.

  1. 資源是由URI來指定.

  2. 對資源的操作包括獲取、創建、修改和刪除資源,這些操作正好對應HTTP協議提供的GET、POST、PUT和DELETE方法.

  3. 通過操作資源的表現形式來操作資源.

  4. 資源的表現形式則是XML或者HTML,取決於讀者是機器還是人,是消費web服務的客戶軟體還是web瀏覽器。當然也可以是任何其他的格式.

REST的要求(為了儘量忠於原意, 這邊我用英文寫):

  1. 客戶端和伺服器結構(Client-Server): Concerns should be separated between clients and servers. This enables client and server components to evolve independently and in turn allows the system to scale.

  2. 連接協議具有無狀態性(Stateless): The communication between client and server should be stateless. The server need not remember the state of the client. Instead, clients must include all of the necessary information in the request so that server can understand and process it.

  3. 能夠利用Cache機制增進性能(Cache): Responses from the server must be declared as cacheable or noncacheable. This would allow the client or its intermediary components to cache responses and reuse them for later requests. This reduces the load on the server and helps improve the performance.

  4. 一致性的操作界面(Uniform Interface): All interactions between client, server, and intermediary components are based on the uniformity of their interfaces. This simplifies the overall architecture as components can evolve independently as long as they implement the agreed-on contract. The uniform interface constraint is further broken down into four subconstraints—resource identification, resource representations, self-descriptive messages, and hypermedia as the engine of application state or HATEOAS.

  5. 層次化的系統(Layered System): Multiple hierarchical layers such as gateways, firewalls, and proxies can exist between client and server. Layers can be added, modified, reordered, or removed transparently to improve scalability.

  6. 所需代碼 (Code on demand, optional): Clients can extend their functionality by downloading and executing code on demand. Examples include JavaScript scripts, Java applets, Silverlight, and so on. This is an optional constraint.

資源(Resource)

“The key abstraction of information in REST is a resource." —Roy Fielding

REST的基本就是對資源的觀念, 所謂資源就是一切可以被存取或操作的東西.

定義資源(Identifying Resoueces): 在你可以跟資源互動或著使用資源之前, 首先你要先能夠定義資源. 在REST中, 我們通常用URI(Uniform Resource Identifier)來定義獨一無二的資源, 其語法為:

scheme:scheme-specific-part

scheme: 如http, ftp或mailto. 這是用來定義語意以及對於URI其他部分的解釋. 舉個例子, 今天有一段URI如下:

http://www.rurumaomao.com/9487945

其中, http的部分就是scheme, 其指出了該HTTP scheme應該要被用來闡釋URI的剩餘部分. 而根據RFC7230裡對HTTP的定義, 我們可以這樣解釋剩餘的部分: 這個URI是位於一個host name為rurumaomao.com的機器上.

URI Template:

  • 一般定義API endpoint的時候, 在資源的部分通常可以考慮用複數名詞, e.g.: api/policies/N1720395748

  • 對unique的資源可以用單數, 那怎麼看是不是單數呢? 可以從當前client的角度來看資源, 若對client來說這份資源是unique的, 那麼考慮用單數是不錯的, e.g.: /customer/notifications, customer是目前經過驗證的客戶, 所以可以用單數

  • API endpoint的設計是可以有層級的, 以保單下的條款來說可以像這樣: api/policies/N1700000001/clauses/123

HTTP方法(我只列出常見的幾個):

方法

說明

特性

GET

取得資源

safe/idempotent

POST

新增資源, 也可當萬用動詞做別的事情

PUT

更新/替換資源

idempotent

DELETE

刪除指定資源

idempotent

PATCH

更新指定資源的部分內容

HEAD

跟GET類似, 但只回傳HTTP header

safe/idempotent

這邊的safe是說該操作不會更動server的狀態且是可以被cache的; idempotent就是中文裡的"冪等性", 即該操作執行了1次跟n次, 結果是相同的, 不過回傳值不見得會相同, 譬如說同樣的資源你delete第二次的時候可能會回傳404(因為已經被砍掉了), 對於idempotent的好處是可以retry多次.

至於很多人喜歡比較POST/PUT/PATCH, 以下是我的看法:

  • POST: 常見用法就是新增資源, 個人認為POST不應該用在update的場合, 因為其本身並不是idempotent的

  • PUT: 通常用來更新特定資源/資源集合體(collection)

  • PATCH:有時候你的資源可能很大, 但你只想更新裡面的一小部分, 甚至是一個欄位而已, 這樣把整個資源重傳一次其實很浪費頻寬, 所以在這種只想更新一小部分的情形中, 就可以考慮用PATCH

HTTP return code:

常見的有這幾群:

  • 2xx: 基本上就是成功的意思, 如200(OK), 201(Created)等等; 對search api來說, 若搜尋結果是空的, 也是200.

  • 3xx: 重新導向

  • 4xx: Client side error, 如401(Unauthenticated), 404(Not found)

  • 5xx: Server side error, 如500(Internal server error), 503(Service unavailable)

Last updated