[TOOLS] 8 分鐘閱讀OraCore 編輯部

用 Actix、SQLx、Postgres 做 Rust …

Rust 後端常見組合是 Actix Web、SQLx 和 PostgreSQL。這套組合主打 async、編譯期 SQL 檢查,還有小體積 Docker 映像,適合直接上線。

分享 LinkedIn
用 Actix、SQLx、Postgres 做 Rust …

Rust 後端圈子很愛同一套組合。Actix WebSQLxPostgreSQL,幾乎是固定班底。說真的,這套不是靠話題撐起來的。

它受歡迎,原因很直接。Actix 給你 async handler。SQLx 幫你抓 SQL 錯誤。Postgres 能扛真實流量。這三個放一起,很多團隊就能少走冤枉路。

這篇整理的是 Marcus Chen 的教學脈絡。Prism News 這週也提到它。重點很簡單:你要做 production API,別先想花俏架構。先把連線池、migration、錯誤處理弄穩。

為什麼這套組合常被選

訂閱 AI 趨勢週報

每週精選模型發布、工具應用與深度分析,直送信箱。不定期,不騷擾。

不會寄垃圾信,隨時可取消。

先講 web framework。Actix Web 4 在 Rust 世界裡,還是很常被拿來當基準。另一個常見對手是 Axum。Axum 跟 Tower 生態綁得很深。你如果團隊已經熟 Tokio middleware,Axum 會很順。

用 Actix、SQLx、Postgres 做 Rust …

但 Actix 的優勢也很明顯。它上線案例多。文件和範例也多。很多人不是想重新設計一套框架,只是想快點把 API 送進 production。這時候,成熟度很重要。

別只看 benchmark。後端團隊不是在交測試報告。你是要處理爛 request、慢 query,還有半夜才爆的依賴問題。這時候,少一點驚喜,比多 5% throughput 更實在。

SQLx 的做法也很討喜。它不把 SQL 包成一堆 ORM 魔法。你還是寫原生 SQL。差別在於,它會在編譯期檢查 query 和 schema。這對 Rust 團隊來說很爽,因為很多錯誤可以在部署前就被抓到。

  • Actix Web 4:HTTP 層主角。
  • Axum:偏 Tower 生態。
  • SQLx:保留原生 SQL,還做編譯期檢查。
  • PostgreSQL:比 SQLite 更適合多 worker 與連線池。

PostgreSQL 這邊幾乎沒什麼爭議。SQLite 很適合本機工具、小型專案、單機應用。可是一旦你要連線池、同步多工、migration 版本控管,Postgres 就比較乾脆。你本機就用 Postgres,部署時通常只是在換環境,不是重做架構。

專案怎麼起手才不會亂

這類教學最有價值的地方,常常不是程式碼本身,而是專案骨架。Cargo.toml 通常會放 actix-websqlx,再開 postgresruntime-tokiomacros。另外還會有 serdedotenvytracingtracing-subscriber。工具面則少不了 sqlx-cli

很多人第一次踩雷,都踩在 runtime。Actix 跑在 Tokio 上。這件事看起來很基本,但不同 crate 對 Tokio 版本或 runtime 的假設,常常會害你在測試時沒事,上線後才出包。這種問題最煩,因為它不會在編譯期直接炸給你看。

另一個很值得早點做的是 logging。tracing 這套很適合 REST API。你可以把 request ID、span、query 時間都串起來。出了問題,不用靠猜。直接看 log 就知道卡在哪裡。

如果你是台灣團隊,我會建議一開始就把環境變數、migration、測試資料庫一起規劃。不要先寫 handler,後面才補。那樣很容易把技術債塞進第一版。

  • #[actix_web::main] 會啟動 Tokio runtime。
  • web::Data 很適合放共享狀態。
  • web::Jsonweb::Pathweb::Query 負責解析輸入。
  • sqlx migratecargo sqlx prepare 應該進流程。

最容易被忽略的細節

Marcus Chen 的教學最有料的地方,是他沒有只講 hello world。真正上線時,最先出事的常常是連線池。這東西看起來很無聊,但它直接決定 latency。池太小,request 會排隊。池太大,Postgres 自己先喘不過氣。

用 Actix、SQLx、Postgres 做 Rust …

所以「一個 worker 配兩條連線」只能當起點。你還是要看 CPU 核心數、Postgres 的 max_connections,還有 query 平均耗時。講白了,這沒有標準答案。要靠實測。

“Building production-grade APIs in Rust has never been more accessible.” — Marcus Chen

這句話我覺得算準。因為這套組合真的把很多麻煩縮小了。SQLx 幫你抓 schema 問題。Actix 把 typed extraction 做得很順。Postgres 則提供穩定的交易和併發模型。

但別誤會,這不代表沒坑。migration 就是一個。SQLx 的 timestamp migration 很好管理,可是如果你忘了更新 offline query cache,CI 可能直接掛掉。尤其是沒連 live database 的 pipeline,更要把 .sqlx 目錄納入版本控管。

另一個常見問題是錯誤映射。很多人會在 handler 裡面亂丟狀態碼。這樣 API 一多,維護就會很痛。比較好的做法,是把資料庫錯誤集中轉成一個 ResponseError enum。

數字怎麼看才不會被帶風向

如果只看效能,Actix Web 常被拿來跟 Axum 比。教學裡提到,在高負載下,Actix 的 requests per second 大約高 10% 到 15%。這是真的有差,但對 CRUD API 來說,通常不是決勝點。

更有感的是部署成本。Rust 的 multistage Docker build,常常可以把 runtime image 壓到 20 到 50 MB。這比很多 JVM 服務小很多,也通常比 Python 服務乾淨。映像檔小,推版快,回滾也比較不痛。

資料庫選型也可以拿來比。SQLx 跟 Diesel 是兩種路線。Diesel 的型別系統很硬,但動態 query 會很卡。SQLx 則保留原生 SQL,async 也比較自然。等你的 API 開始有可選 filter、join、排序時,你會更懂這差別。

  • Actix Web 對 Axum:高負載下約快 10% 到 15%。
  • Rust Docker runtime image:常見 20 到 50 MB。
  • SQLx 對 Diesel:SQLx 偏原生 SQL,Diesel 偏型別建構。
  • PostgreSQL 對 SQLite:Postgres 更適合多 worker 與併發寫入。

測試這塊也不能省。你可以用 Dockerized Postgres 做 integration test。再搭配 sqlx::test macro。這樣很多 schema 問題、交易問題、SQL 語法問題,都能提早抓到。

CI 方面,GitHub Actions 加一個 Postgres service container 就夠用了。不用一開始就搞很重的基礎設施。先讓 build 誠實,再談優化。

這套組合放在產業裡的位置

Rust 後端這幾年慢慢進入更實際的場景。不是每家公司都要用 Rust。這點要講白。可是如果你的服務很在意 latency、記憶體用量、資料一致性,Rust 就很有吸引力。

Actix、SQLx、Postgres 這套組合,剛好把三件事接好。HTTP 層、資料層、資料庫層,都有成熟工具。你不用自己拼一堆輪子,也不用把 SQL 藏進一個很厚的 ORM。

這也是為什麼很多團隊會把它當正式後端,而不是實驗品。你可以先做內部 API,再慢慢擴到對外服務。路徑很清楚。風險也比較可控。

如果你是從 Node、Python 或 Go 轉過來,最需要適應的不是語法,而是思考方式。Rust 會逼你把資料流、錯誤流、生命週期想清楚。剛開始會覺得煩。可是一旦你把框架搭穩,後面就很少有那種「怎麼又炸了」的驚喜。

我會怎麼下結論

如果是我這週要開新 API,我會直接用這套。HTTP 層選 Actix Web。資料層用 SQLx。資料庫選 PostgreSQL。第一天就把 migration、log、測試資料庫放進流程。不要等到第二版才補。

我也會把錯誤處理集中管理。別在每個 handler 裡各寫各的。那樣 API 一多,維護會很痛。還有,別把 async 想得太神。async 只是把問題搬到別的地方。連線池、runtime、schema 一樣要管。

我的預測很簡單。接下來會有更多 Rust 團隊,直接把 Actix、SQLx、Postgres 當標配。不是因為它最潮。是因為它夠直白,也夠能打。你如果現在在選 backend stack,我會先問一個問題:你想讓 compiler 先抓錯,還是想讓半夜的 pager 幫你抓?