解釋整個專案框架的選用以及原因
核心原則很單純:快速開發、容易維護,不過度工程。
因此技術選擇上,希望盡量維持同一套開發語言。整個專案主要採用 JavaScript / TypeScript 生態系:前端使用 React,後端則使用 Node.js Runtime 跑在 AWS Lambda 上,讓前後端的開發方式比較一致,也降低切換不同語言的成本。
前端選擇 React,主要是想趁機熟悉目前主流的前端 UI Library。React 採 Component-based 的方式組合畫面,很適合把表單、營養分析結果、餐點建議等功能拆成獨立元件;同時本身對專案架構的限制不多,對需要快速產出 MVP 的個人專案來說相對有彈性。
React 本身只負責 UI,開發伺服器、TypeScript 處理、Hot Reload 與正式環境的 Build,則交給 **Vite,**可以把它理解成 React 專案的「開發與打包工具」。Vite 在開發模式下用原生 ES Module 與 HMR,瀏覽器直接載入,修改程式碼後幾乎可以立即看到結果,比我過去熟悉的 Angular CLI 開發體驗輕量許多,因此選擇設定簡單、開發速度快的 Vite。
前後端都使用 TypeScript,共用同一種語言、共用型別定義(例如 API 的 Request/Response interface),減少”前端猜後端格式”的溝通成本。靜態型別能在寫程式當下就抓到拼字、型別錯誤,比純 JavaScript 除錯快,也更容易上手。
ESLint 負責程式碼的靜態檢查,除了統一寫法之外,也可以透過 React Hooks 等規則提早發現一些容易忽略的問題,例如未使用變數、錯誤的 Hook dependency 等,生態成熟、規則完整、文件與除錯資源也比較多。
畫面樣式使用 Tailwind CSS v4,可以直接在component中組合,不用額外建立CSS class,這種方式可以很快調整畫面。
後端使用 AWS Lambda。一方面可以延續 Node.js + TypeScript 的寫法;另一方面,我也想藉這次專案真正實作一次 Serverless 架構。
Lambda 最大的特色是不用自己維護一台長時間運作的 Server,當 API Request 進來時,AWS 才執行我的程式,對一個沒有固定流量的 Side Project 來說,不需要為閒置 Server 持續付費,也不用處理太多伺服器維運問題。
Lambda 等 AWS 資源則使用 AWS SAM(Serverless Application Model) 管理。之所以選 SAM 而不是直接使用 CloudFormation,是因為這個專案幾乎都是 Serverless 資源,而 SAM 本來就是 AWS 為 Lambda、API Gateway 等 Serverless 架構提供的簡化工具。
使用 AWS CLI 從 Terminal 操作 AWS。相較於Console 網頁介面不方便重複操作,CLI 更適合記錄成可重複執行的指令,也方便寫進這系列文章裡當步驟記錄。
IAM可以理解成一種權限管理,最簡單理解就是使用者是誰? 可以對哪個資源? 做什麼事情? 在AWS中幾乎都是使用IAM角色來做管理。
Bedrock 本身不是一個 AI 模型,而是 AWS 提供的生成式 AI 平台,可以透過同一套 AWS 架構使用不同 Foundation Models。選 Bedrock 而不是直接串外部 AI API,其中一個重要原因也是它可以直接整合 AWS IAM。不需要另外在程式裡管理一組第三方 API Key,和 Lambda、CloudWatch 等 AWS 服務整合起來也比較一致。
資料層不上資料庫,只用一份 S3 存的 foods.json。雖然看似有些陽春,但若一開始就導入 PostgreSQL、DynamoDB、向量資料庫、Schema Migration 等技術,反而會增加不少目前根本用不到的複雜度,違反這次專案開發的原則”簡單不過度工程”,實際跑起來都夠用,而且如果後續要升級也不是不行。