[Day 6] API Service

erichung0404
2024-08-06 19:15:24

有了 Database 後, 我們已經可以有效率的 增查改刪 (CRUD, Create, Read, Update, Delete)
且 Database 都會提供自己的 Query API, 比如

RDBMS: SQL

Cassandra: CQL

MongoDB: MQL

(每種 Database 的 Query API 都有自己的特點與語法, 如有興趣請自行查閱)

由於 Database 通常會用於儲存敏感性資訊如: 使用者資料, 所以只能允許 "我們自己的服務" 請求
簡單說就是把 Database "藏起來", 避免資料外洩
(請見 此新聞)

有以下幾種方式

內部網路 (防火牆, Private IP, etc)

VPC (Virtual Private Cloud)

Database ACL (Access Control List)

不是今天的重點, 所以僅簡單帶過

既然 Database 被藏起來了, 客戶端就需要透過 "公開的" API Service 操作資料

客戶端和 API Service 的溝通有幾種模式

Request-Response

Polling

Long Polling

Server Push

Websocket

Publish-Subscribe (PubSub)

題外話: 和 Linux I/O Model 有點像, Request-Response 對應到 Blocking I/O; Polling 對應 Non-blocking I/O; Long Polling, Publish-Subscribe 對應 Asynchronous I/O

Publish-Subscribe 留到 Message Queue 的時候再說~

Request-Response

最常見的架構, 由客戶端發起請求, 等待伺服器收到並處理後回覆

適合用在非即時的情境如: 瀏覽網頁, 遊戲排行榜, 銀行餘額檢查, 搶購商品等等可以接受非即時更新的情境

Polling

客戶端定時發起請求給伺服器, 每次都會等待伺服器處理後回覆

通常用在如 Heartbeat, Health Check, Keep Alive 等不涉及複雜處理的輕量操作

缺點

每次都要重新建立連線 (Handshake), 很花時間

Long Polling

Polling 的變種, 和 Request-Response 模式不同, 客戶端發送請求後, 伺服器收到不會立即回覆, 而是保持連線開啟, 等到有更新才回覆
你可能會想: 這樣不會 timeout 嗎?
沒錯! 由於這種連線方式很脆弱, 只要客戶端或伺服器斷線, 雙方就失去彼此了QQ
所以只要斷線或連線結束 (伺服器更新狀態後馬上回覆) 的話, 客戶端就會馬上再發一個新的請求給伺服器

不確定真實應用場景, 但 Server Push 的使用情境應該都 "可以" 使用 (不代表最適合) Long Polling, 如: Alert System, 聊天系統, 系統監控等等

缺點

和 Polling 一樣, 每次都要重新建立連線 (Handshake), 很花時間

要維持連線開啟, 但是沒更新時又用不到, 浪費資源

題外話: 我的認知是 Long Polling 是 Websocket 的下位替代, 通常是無法使用 Websocket 的情境 (如防火牆, Proxy) 才會用 Long Polling, 但是沒有 reference, 看過就好囧

Server Push

以下介紹兩種 Server Push 的實作: SSE, HTTP/2 Server Push

Server Sent Events (SSE)

相較於 Long Polling 用比較 hacky 且每次都要重建連線的方式 "讓伺服器通知狀態", Server Push 就是真的 "從伺服器通知"
另一種技術是 Server-sent events (SSE), 可以用瀏覽器的 EventSource API 達成

不知道有什麼 "專門的" 使用情境, 感覺已經沒有人在用了囧
所以不多作介紹

另一種是 HTTP/2 Server Push

HTTP/2 Server Push

為了解決過去 HTTP/1.1 無法有效率的達成 Server Push 的問題
HTTP/2 就實作了 Server Push!

時間原因就不詳述, 有興趣請見以下參考

RFC 7540

HTTP/2 in Action

主要針對 靜態資源 (html, css, js, multimedia 等等) 優化, 加入網頁的讀取速度
但是針對其他資料如 streaming, multipart 資料傳輸類型就不支援

所以適用情境為: 頁面加載優化, SEO 優化 (加載速度快的好處)

Websocket

Websocket 支援 "雙向傳輸", 所以上述 Long Polling 和 SSE "理論上" 都可以用 Websocket 代替

大致流程如下

1. 客戶端發送請求給伺服器以建立 TCP 連線 (Handshake)

2. 客戶端在請求的 header 帶上一些參數 "要求" 伺服器升級成 websocket 連線 (不一定會成功, 伺服器可能不支援囧)

3. 伺服器收到請求並接受後, 回覆客戶端

4. 客戶端收到並確認沒問題後, 就可以開始透過 websocket 連線了!

缺點是如果某些 伺服器 不支援 Websocket, 就會在第 2 步失敗, 無法建立連線, 這時候就需要改用其他 Server Push 機制

適用情境有: 聊天系統, 即時遊戲排行榜更新等需要雙向溝通的情境

Reference

[新聞] 某公司資料庫資料外洩

EventSource API

RFC 7540

HTTP/2 in Action