你好!
我是從35歲開始、沒有相關經驗學習 Web 的一位學習者。
我整理了自己對「Web API」和「REST」的理解,並把它寫成一篇文章。
這次為了好想像,我用「家庭餐廳的點餐」作比喻來說明。
如果對同樣在學習的人有幫助,我會很開心!
這篇文章適合這些人閱讀
・對「API」這個詞還有些抗拒的人
・對 REST 或無狀態(stateless)的意義有些模糊的人
・想把基礎重新用簡單方式整理一遍的人
一句話來說,
就是這樣!
API(Application Programming Interface,應用程式介面)是
用來讓電腦互相溝通的「規則(規格)」。
具體例子:家庭餐廳的菜單
假設你去了一家家庭餐廳。
如果直接對廚房大喊「幫我做漢堡排!」,通常會被趕出去吧。
這時候登場的就是「菜單(API)」。
菜單裡會決定以下三件事:
名稱: 「A 套餐」
參數(引數): 「白飯加大」
結果(回傳值): 「漢堡排跟加大的白飯會送來」
這個「說了什麼(輸入)、會做什麼(輸出)」被事先定好,這個窗口就是 API。而把它放在網路上(透過 HTTP)可以使用的,就是「Web API」。
Web API 並沒有「一定要這樣做」的硬性法律。
因為自由,有時會出現彼此不一致、難以使用的 API。
於是有人提出了「如果用這些規則做,大家會比較好用!」這樣的設計指引,這就是「REST」。遵守 REST 規則的 API 常被稱為「RESTful API」。
REST 有幾個特別重要的特性,這裡說四個。
每個資訊都有一個唯一的「URL(位址)」。
不是用「那個~給我一份那個」這種模糊的點法,
而是要像這樣明確指定:
「https://api.example.com/menu/hamburg」
也就是能夠明確地以位址去取得你要的資源。
把溝通方式統一為固定的方法,例如:
「GET(取得)」「POST(建立)」「PUT(更新)」「DELETE(刪除)」
就像去任何一家店都知道「點餐=點菜」「結帳=收銀」一樣,不會迷路。
伺服器不會記住「你過去的點餐(狀態=state)」,也就是完全不保留之前的記憶。
【一般對話(有狀態,stateful)】
客人:「我要漢堡排」
店員:「好的」
客人:「啊,改成剛剛那個加大」
店員:「了解!(剛剛是漢堡排吧)」
【REST 式對話(無狀態,stateless)】
客人:「我要漢堡排」
店員:「好的」
客人:「啊,改成剛剛那個加大」
店員:「……剛剛是哪一次?(記憶斷片)」
對於遵守 REST 的店員來說,每次都必須把「我要漢堡排、白飯加大」等所有必要資訊一次說清楚。
這樣做的原因是,如果店員(伺服器)要為每位客人記住狀態,客人一多就會忙不過來。透過「不記憶過去」,任何店員(伺服器)都能照同樣方式處理請求,系統就能比較容易水平擴充(增加伺服器)。
回傳的結果中應包含指向下一步相關資訊的連結。
像在 Amazon 買東西會出現「買了這個的人也買了這些」的連結一樣。
來用圖看程式之間怎麼溝通。
【Client(你)發出的點餐】
GET /api/v1/users/35age-beginner
Host: example.com
(含意:example.com,給我35歲、沒有經驗的工程師資訊!)
⬇︎
⬇︎(越過網際網路的風浪……)
⬇︎
【Server(餐廳)回覆】
{
"id": 1,
"name": "wata-shoさん",
"status": "學習中",
"comment": "腰和眼睛很痛"
}
(含意:好喔!現在的狀態是「學習中」,而且有腰痛和眼睛不舒服喔!)
像這樣,對人來說只是字串,但電腦之間其實在正常對話。
REST 設計簡單易懂,但當 Web 服務變複雜時,有時會覺得「有點難處理」。
例如可能會回傳過多不必要的資料,或是為了取得想要的資訊必須組合多個 API 才能完成等情況。
為了應對這些問題,也出現了其他的做法。
GraphQL:
像是「請給我漢堡排的肉、1 根薯條、還有一口可樂!」這樣可以只取需要的資料的機制。
RPC 風格:
把遠端伺服器上的功能,當作自己電腦上的函式一樣直接呼叫的風格。
現在已經不是「只有 REST 一條路」了,會視系統需求來選擇使用這些不同的方式。
把 Web API 和 REST 的要點簡單整理成三點!
・API 是「程式之間溝通的點餐窗口」
・REST 是「為資源定位置(URL)、不保留記憶(無狀態)、以簡單方式溝通的設計風格」
・會依需求搭配使用 GraphQL、RPC 等其他方式
當你開始了解 API 的思維後,
平常使用的服務底層會慢慢變得比較好懂,也滿有趣的。
下次文章再見!