休息(REST)式架構? 寧靜式(RESTful)的Web API是現在的潮流?
好拉,其實這笑話一點也不好笑,本文是要介紹常見的五種HTTP Method
作者: Vincent Ke 更新日期: 2020/10/03
我們談到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的