在上一篇文章中,我們成功將前端資源掛上 CDN,並透過 OAC 使得我們的 S3 物件資源被保護得好好的,而今天,我們從「請求的角度」出發,探討後端的 API 設計與 AWS Lambda 的角色,結合 Serverless 和 RESTful API,提升多人協作平台的可維護性與擴展性,順便聊聊鬆耦合架構,看看事件觸發的可能性。
如同我們之前介紹的,Lambda 是一個 Serverless、Function as a Service (FaaS) 的服務,可以透過與 API Gateway 串接作為響應系統。
但當我們更深入一點時,Lambda 的幾個特性會成為我們做後端系統設計的重要依據:
上述幾個特性讓 Lambda 變得很強,不過基於 Lambda 的後端系統也會有一些侷限性,例如無法長期記憶、需要拓展性導致的無法管理 Session 等
於是很多時候的 Context 即需要靠事件來帶入
而因此在系統中的實作,我們理所當然只能採用Stateless的設計哲學
舉個之前我們處理過的使用者管理為例子,透過 AWS Cognito,我們可以經 OAuth Flow 取得使用者識別 Token,再交給 API Gateway 依照請求來解析,如此一來 Lambda 完全不需要知道使用者有哪些,只需要解析請求所帶 Token 就好了,這就是 Stateless
在這種架構下,我們通常會搭配 RESTful API 來實現無狀態後端:
/projects
、/projects/{projectId}/events
。GET
讀取資料、POST
新增、PUT/PATCH
更新、DELETE
刪除。透過 RESTful API + Lambda 的組合,我們能建構一個 雲原生、可水平擴展且易於維護的後端系統,同時保持無狀態與模組化。
以我們的多人日曆共編平台為例,從使用者的請求出發我們大致上可以把需求分成三大塊
那麼以後端架構而言,我們就可以這樣子設計:
依照需求劃分功能模組,一個 Lambda 管一件事,拆分得清清楚楚
設計架構時我們會希望盡量滿足以下幾個原則:
PoLP(最小權限):
(如果在多表設計的情境)
CreateEventLambda
→ 只可寫入 Events
TableDeleteProjectLambda
→ 只可刪除 Projects
TablePoLR(最小責任):
這樣子設計出的元件相互依賴性不會過於混雜,系統若是需要大改就只需要局部更新,一個一個組件更新、上線,算是 Microservice( 微服務 ) 概念的基礎
當業務邏輯複雜度上升時,例如我們要新增一個功能:任務快到期時自動提醒使用者,如果每個 Lambda 都直接呼叫其他 Lambda 或服務,程式碼會很快變得難以維護。
這時候可以採用 事件驅動(Even-Driven) + 鬆耦合 的方式:
Task Service
負責任務狀態管理Task Service
發布一個事件,例如 TaskDueSoon
SNS
:送出通知給使用者(也可用 SES / Lambda 直接呼叫 API)UpdateStatsLambda
:更新任務統計資料TaskDueSoon
就行,不會影響現有流程AWS 服務提示:EventBridge 可做事件總線,SNS/SES 負責通知,Lambda 處理業務邏輯,保持每個元件只做自己的事(PoLR)。
如此一來在微運/系統更新上都可以享受鬆耦合的優勢,服務不必下線也可以增加新功能
透過 Event-driven 架構,我們看見 Lambda 不只是單一的請求-回應邏輯,而是能在整個系統中,成為事件流中的一個組件。這樣的設計,讓我們的平台具備了更好的彈性與擴展性。
不過,當服務之間的互動越來越複雜,另一個問題隨之而來:我們要如何有效追蹤、監控並維護這樣的 Serverless 系統?
這將是我們在下一篇要深入探討的重點 —— Serverless 架構下的可觀測性 (Observability),以及如何透過 AWS 提供的工具(如 CloudWatch、X-Ray)來確保系統在規模成長的同時,依然能保持穩定與透明。