進度條

[不是工程師] 休息(REST)式架構? 寧靜式(RESTful)的Web API是現在的潮流?

好拉,其實這笑話一點也不好笑,本文是要介紹常見的五種HTTP Method

作者: Vincent Ke 更新日期:

在前一篇文章中,已經進入SaaS / PaaS / IaaS 時代已久,還在用舊時代想法規劃網站嗎?

 

我們談到Saas以及Web API在現在軟體開發業的前瞻性及商業價值,而現在市場上主要使用Web API來作為呼叫Web Service的仍佔多數。

 

 

當然你也可能是被喝醉酒的頑皮豹圖片給騙進來,總之被騙進來就繼續看下去吧!

 


本文已被校正小編修改太多,但還是列原作者的名字。
特別註明與此,避免如果校正小編有編寫上的錯誤被算到原作者身上。
 

 

 

REST其實是縮寫,它當然不是休息的意思,RESTful也不是翻寧靜式,不過這裡先賣個關子,因為再講REST / RESTful 之前,我們必須要先提起幾個HTTP協定。


在HTTP協定中,定義了多種不同的method做為服務的請求方法,近年來由於行動裝置的普及化,越來越多的產品及網站,都提供了WebAPI服務,因此身為程式設計師的我們,在設計API為主的Web服務時,對於HTTP請求方式的認知,更是相當重要。

 

 

最常見的method,小編已經列出五種如下:
GET
POST
PUT
PATCH
DELETE

 


所有的字看起來既熟悉又陌生,因為在Http的協定下,每一種呼叫方式都會有一種他專屬的特殊定義,對於寫過網站的人來說,GET和POST絕對毫不陌生。

 

當Web service使用Web API進行介面介接時,每一串我們設計的URL,就會是一個專屬的服務『窗口』。

舉例來說,像是讀取及上傳的動作,就屬於完全不同的業務,所以當然也會用不同的呼叫方式來設計。

 


簡單說,不同的Method就是對同一件事情做不同的操作

 

以上一篇搭買鞋子為例子去做衍生吧!

 

 

 


GET:取得型錄,了解想要找的鞋子、型號、規格等。
POST/PUT:呼叫店員協助幫忙找鞋子,並買到想要的鞋子。
PATCH:結帳後向店員更換尺寸或加價購買其他配件如鞋帶、襪子等。
DELETE:跟店員說我不要了。

 

用生活化的例子講解完後,改以程式的角度來說明

 

GET:取得(想要的服務)的資料或是狀態。(safe & idempotent)
POST:新增一項資料。
PUT:利用更新的方式於"指定位置"新增一項資料。 (idempotent)
PATCH:在現有的資料欄位中,增加或部分更新一筆新的資料。
DELETE:指定資料刪除。 (idempotent)

 

這裡突然出現了兩個名詞safe & idempotent,這兩個是HTTP狀態描述的專有名詞。

 

「safe」是指該操作不會改變原本的資源狀態,並且同樣的結果是可以被快取(Cache)的。例如: 查看訂單是不會改變訂單本身紀錄。

 

「idempotent」是指該操作不管做1遍、2遍或多遍,都會得到同樣的資源狀態結果。例如: 同一筆資料被DELETE了2次,雖然都是一樣的結果,但第二次發送會因為資料已經被刪除而失敗喔!


 

GET / POST 我們用得很多所以沒什麼問題,DELETE與字意上相符所以不難理解。其中讓人困擾的是PATCH & PUT,要解釋它們必須參考定義(RFC 5789)。

 

依照RFC 5789

POST/PUT 都可以用來新增,

PATCH/PUT 都可以用來修改,

但其中的差別在哪裡呢?

 

POST的定義上屬於將原先沒有的資料去做一筆新增的動作,PATCH就是一般常見的修改,所以真的有問題的其實是PUT。

PUT在定義上(idempotent)無論做多少次,回傳結果都會一樣

 

 

以POST來說,我要一雙鞋,我就會得到一雙鞋。但是如果再用POST發一次我要一雙鞋,會出現兩種可能:

1. 我"再"得到一雙鞋,而且這雙鞋跟上一雙是不一樣的,以資料庫來說,就是ID不一樣。

2. 我只能有一雙鞋,所以他會跟我說"錯誤",我已經得到一雙鞋了!

 

但以PUT來說,無論我發多少次,他都會回我,我有一雙鞋,而我並不會變成兩雙鞋。當然如果商店沒鞋,則變成我沒有鞋。

 

這點在很多程式框架裡面都不完全正確,像Ruby On Rails的PUT與PATCH看起來是一件事(當然你可以自己修正)。

定義是絕對的,但應用是彈性的,所以你可以說這些框架做的與RFC5789不一樣,但或許這樣比較好用。

 

這就看個人取捨,當然,考試的時候通常需要寫RFC5789的定義。

 


另外,PUT除新增外亦可以做更新請求,假設使用PUT 做更新,不管是既有的資料或是覆蓋原先的資料,都會利用覆蓋的方式去更新,但假如你的資料裡面有圖檔的話,每PUT一次,圖檔就必須要再重新上傳一次,是相當耗費資源的。

 

 

而PATCH則可以針對已經存在的資料欄位去做部分更新。

例如:我們在更新履歷表時,使用PATCH就可以僅更新裡面的資料,如年齡、工作經歷等欄位,而PUT就像是把整份改好的履歷表重新上傳。

PATCH也可以更新本身一開始PUT資料內沒有的欄位,故PATCH是非屬於idempotent  的操作。

 

 

 


所以如果我們以電腦操作檔案來譬喻

建立一個新檔案是POST

修改檔案是PATCH

從別的地方複製檔案貼上就是PUT (無論你貼上幾次都是同一個檔案)

 

當然Web API沒有一定要照著上面的定義敘述建立,但如果你符合的話,你可以將它稱作Restful API。

(Rest化 = Restful,如果像小編一樣常常不知道講述的時候該用Rest或是Restful可以這樣去記,被轉化成Rest架構的Web API = Restful API)

 

 

REST全名 Resource Representational State Transfer ,可譯為具象狀態傳輸,若是把各個單字拆開來解釋的話即如下:

 

Resource:資源。

Representational:表現形式,如JSON,XML...

State Transfer:狀態變化。即上述講到的可利用HTTP動詞們來做呼叫。

 

簡單的說,就是一個單從發出的HTTP要求裡面所包含的資訊,就可以直接預期這要求會收到怎樣類型的資料。再更白話一點,就是人眼看得懂。

 

 

 

 

REST指的是網路中Client端和Server端的一種呼叫服務形式,透過既定的規則,滿足約束條件和原則的應用程式設計,對資源的操作包括獲取、創建、修改和刪除資源,這些操作就是依照我們前面所提到的HTTP Method: GET、POST、PUT、PATCH和DELETE。這正好會對應到資料庫基本操作CRUD。

CRUD 為 Create(新增)、Read(讀取)、Update(更新)與Delete(刪除)的縮寫。

 

 

接著我們繼續舉例來說(這文章舉好多例子...)

 

 

如果我們在寫一隻商品的WebAPI,讓工程師隨便寫可能會有以下方式來作interface:

獲得商品資料 GET   /getAllItems
獲得商品資料 GET   /getItem/11
新增商品資料 POST /createItem
更新商品資料 POST  /updateItem/
刪除商品資料 POST  /deleteItem/

 

若是以使用 RESTful API 開發的話:

獲取商品資料 /GET     /items
獲取商品資料 /GET     /items/1
新增商品資料 /POST   /items
更新商品資料 /PATCH /items/1 
刪除商品資料 /DELETE /items/1

 

PUT 則是比較特別一點,其實它並不直接對應CRUD裡面的任何一項。

 

 

在這樣的風格中最有名的,應該就是大家不陌生的Ruby on Rails了吧(偷偷講,我們有線上課程喔)!透過 HTTP 為基礎來設計 RESTful API,不僅可行,更可以更簡單扼要呢!

 

最後要提醒大家,你沒辦法直接在HTML的<form>裡面使用GET 與 POST以外的Method。因為瀏覽器都還不支持。如果你想要發送Restful request 一般都要後台程式的支援,而且必須要在<form>裡面藏一個:

 

<input name="_method" value="你的HTTP Request方法" />

 

才有辦法送出去喔!

 


最後,如果你喜歡我們的文章,別忘了到我們的FB粉絲團按讚喔!!

Medium vincent

Vincent Ke

喜歡把混亂的事情變的簡單 用嘴巴做事其實很可以 但要結合靈活的腦袋思考 就一起來拆解吧