1. 什麼是 API?
應用程式介面(英語:Application Programming Interface)
想像API是服務員,你來到了餐廳,看了菜單(API Doc),點了你想要的項目(Request)。經過廚師的努力(Server),服務員將菜端出來(response)給你。
1.1.以API 公開性大概可以分為三類
- Open API又稱作Public API
Developers(開發商)它還是需要去Register(註冊),Sign up 取得key。給大眾使用的API - Internal API
公司內部使用,串聯不同service,不同team之間 - Private API
有授權使用,透過合作或付費方式
1.2.以 protocol 與 architectural角度來分
- Local APIs
The original API, created to provide operating system or middleware services to application programs. - Web APIs
Designed to represent widely used resources like HTML pages and are accessed using a simple HTTP protocol.Often called REST APIs or RESTful APIs. - Program APIs
Based on RPC technology that makes a remote program component appear to be local to the rest of the software
2. 什麼是 REST?
REST 是 Representational State Transfer 的縮寫,可譯為「具象狀態傳輸」。由 Roy Fielding 博士在 2000 年的博士論文中所提出。他同時也是 HTTP 規範的主要作者之一。符合 REST 風格的網站架構可以稱為 RESTful。
REST 是一種軟體架構風格(並非標準),目的是幫助在世界各地不同軟體、程式在網際網路中能夠互相傳遞訊息。每一個網頁都可視為一個資源(resource)提供使用者使用,而你可以透過 URL(Uniform Resource Locator),也就是這些資源的地址,來取得這些資源並在你的瀏覽器上使用。
REST指的是網路中Client端和Server端的一種呼叫服務形式,透過既定的規則,滿足約束條件和原則的應用程式設計,對資源的操作包括獲取、創建、修改和刪除資源,這些操作就是依照我們前面所提到的HTTP Method: GET、POST、PUT、PATCH和DELETE。這正好會對應到資料庫基本操作CRUD。
CRUD 為 Create(新增)、Read(讀取)、Update(更新)與Delete(刪除)的縮寫。
3. 什麼是 RESTful?
運用 HTTP 來表達語義的路由設計風格稱為 RESTful API。
(Rest化 = Restful,如果像小編一樣常常不知道講述的時候該用Rest或是Restful可以這樣去記,被轉化成Rest架構的Web API = Restful API)
HTTP 本身就是 REST 的實作
4. REST和RESTFUL的區別?
經過大量資料閱讀,我只能這樣詮釋:就好比Beauty和Beautiful的關係。
5. RESTful API 主要由三種元件組成
- Nouns 名詞:定義資源位置的 URL,每個資源在網路上都會有唯一的位置,就如每戶人家都有唯一的地址一樣。
- Verbs 動詞:對資源要做的動作。
- Content Types 資源呈現方式:API 資源可以以多種方式表現,最常用的是 JSON,較輕,也較好處理。
不同公司,不一樣的工程師,設計的名稱都會不一樣,沒有統一的命名方式,造成在引用各家 API 時,都需要詳讀 API 文件,理解所有設計命名規則後,才可使用。
6. REST 優點與限制
- 有唯一的URL表示資源位置,統一的 API 接口。(Uniform Interface)
- 無狀態。(Stateless)
RESTful 的狀態,意即 HTTP 的請求狀態,一般 Web 服務中,Server 端和 Client 端交互的資訊,會存在 Server 端的 Session (例如:已登入狀態),在 Client 端再次發送請求的時候,Server 端透過保存在 Server 端的 Session,去執行 request。無狀態的意思,即 Client 端自行保存狀態,在請求 Server 的時候,一併附上給 Server 端,Server 端無保存 Client 端的狀態資訊。
舉例來說,可能在用戶登錄系統時,Server 產生 token 紀錄 user 已登錄系統,然後把 token 還給 Client,在 Client 再次發送請求的時候,把 token 一起發給 Server,這樣 Server 就知道這一個 Client 是已經處於登錄的狀態。
意即所有的資源都可以 URI 定位,而且這個定位與其他資源無關,也不會因為其他資源的變化而變化,資源相互的依賴性降低。
舉一個白話一點的例子:查詢員工工資:
第一步:登錄系統。
第二步:進入查詢工資的頁面。
第三步:搜索該員工。
第四步:點擊姓名查看工資。
這樣的操作流程就是有狀態的,查詢工資的每一個步驟都依賴於前一個步驟,只要前置操作不成功,後續操作就無法執行。如果輸入一個URL就可以直接得到指定員工的工資,這種情況就是無狀態的,因為獲取工資不依賴於其他資源或狀態,這種情況下,員工工資是一個資源,由一個 URL 與之對應可以通過 HTTP 中的 GET 方法得到資源,這就是典型的 RESTful 風格。 - 可更高效利用快取來提高回應速度 (Cachable)
在 server-side,GET 過的資源,如果沒有被變更過,可以利用 cache 機制減少 request。
在 client-side,透過 client 端 cache 紀錄 cache 版本,若向 server 要求資源時發現 server 最新版與 cache 相同,則 client 端直接取用本地資源即可,不需要再做一次查詢 - 分層系統架構 (Layered System)
- 客戶端服務器分離 (Client-Server)
- 充份利用 HTTP protocal(GET/POST/PUT/DELETE) (Manipulation of resources through representations)
- 可執行程式碼的設計,像是 JavaScript(非必要實作項目) Code-On-Demand (optional)
6.1. 好處
RESTful 這種「和 CRUD 對齊」的特性會帶來一些溝通的便利性,客戶端只需要知道可用資源,就能依照約定俗成的邏輯,推測出相關的 API。
這種「約定俗成」的設計感也可以讓工程師規劃路由時減少一些煩惱。
6.2. 壞處
REST 也不是萬能的,除了優點也是有許多在實務上應用的缺點。比如查詢時常被詬病資源相依結構鬆散問題,有時候取資料時都要呼叫好多次 API 才可以組合成完整的物件。舉個例子,想要取得文章與作者資訊,就必須先 GET /文章/{ID},然後再透過取回的文章物件中的 Author 欄位再一次呼叫 GET /使用者/{NAME} 取得作者資訊,挺麻煩的。像是最近興起的 GraphQL (由 Facebook 發佈) 就可以解決 REST 取相依結構資料的問題,整體來說 ORM 的實踐概念更好了,也剛好呼應近幾年熱門的 NoSQL 設計
當然,一個專案裡不可能所有的路由都在操作資料,因此不會每條路由都能完美對齊 RESTful,例如「登入」的路由通常設定為 POST /login,就完全是以動詞為中心。身為專案的架構者,有時候還是需因地制宜,風格只是參考,不是阻礙。
7. PUT 需要注意
POST/PUT 都可以用來新增,PATCH/PUT 都可以用來修改,但其中的差別在哪裡呢?
POST的定義上屬於將原先沒有的資料去做一筆新增的動作,PATCH就是一般常見的修改,所以真的有問題的其實是PUT。
PUT在定義上(idempotent)無論做多少次,回傳結果都會一樣。
以POST來說,我要一雙鞋,我就會得到一雙鞋。但是如果再用POST發一次我要一雙鞋,會出現兩種可能:
- 我”再”得到一雙鞋,而且這雙鞋跟上一雙是不一樣的,以資料庫來說,就是ID不一樣。
- 我只能有一雙鞋,所以他會跟我說”錯誤”,我已經得到一雙鞋了!
8. 使用回傳 HTTP 狀態碼 (Status codes) 來表示執行結果如何
HTTP 中也規範了各種狀態碼,來表示請求是否被完成,因此 API 在回應時也應回傳適當的 HTTP 狀態碼,來表示執行結果。HTTP 狀態碼的大分類如下:
1XX 訊息 (Informational)
2XX 成功 (Successful)
3XX 重新導向 (Redirection)
4XX 請求錯誤 (Client Error)
5XX 伺服器錯誤 (Server Error)
9. 實作
PYTHON FAST API
index.py
1 | from fastapi import FastAPI |
index.html
1 | <!DOCTYPE html> |
10. 其它ISSUE
避免API被攻擊,可以考慮啟用API調用速度限制(Rate limiting),又或是HTTP Cache的機制
狀態碼
2xx = Success(成功)
3xx = Redirect(重定向)
4xx = User error(客戶端錯誤)
5xx = Server error(伺服器端錯誤)
11. 延伸閱讀
- RPC
- SOAP
- REST
- GraphQL
11.1. WEB SERVICE 分四種
- JSON-RPC
- SOAP
- XML-RPC
- REST