從零構建Rust生產級服務

溫祖彤,李力,楊楚天

  • 出版商: 電子工業
  • 出版日期: 2024-09-01
  • 售價: $1,008
  • 貴賓價: 9.5$958
  • 語言: 簡體中文
  • 頁數: 560
  • ISBN: 7121487071
  • ISBN-13: 9787121487071
  • 立即出貨 (庫存=1)

買這商品的人也買了...

相關主題

商品描述

本書是一本面向 Rust 後端開發人員的入門參考書,通過實際項目引導讀者從 0 到 1 構建一個功能齊全的電子郵件通信API。本書涵蓋了廣泛的主題,包括 Rust 生態系統的利用、應用結構的設計、測試的編寫、用戶認證和授權、錯誤處理策略的實施、應用狀態的觀察,以及持續集成和部署管道的建立等。本書不僅介紹了具體的工具和庫,還深入探討了系統設計、可觀測性和易操作性等重要概念,能夠幫助讀者掌握專業的開發方法。 本書適合初學者,是開啟 Rust 開發之旅的理想起點,即使沒有 Rust 或後端開發經驗,相信你也能夠輕松跟上、快速入門。

目錄大綱

第1章 準備工作 1
1.1 安裝Rust工具鏈 1
1.1.1 編譯目標 1
1.1.2 發布渠道 2
1.1.3 我們需要什麽樣的工具鏈 2
1.2 項目初始化 3
1.3 集成開發環境 3
1.3.1 rust-analyzer 4
1.3.2 IntelliJ Rust 4
1.3.3 應該如何選擇IDE 4
1.4 內部開發循環 5
1.4.1 更快的鏈接 5
1.4.2 cargo-watch 6
1.5 持續集成 7
1.5.1 持續集成的步驟 8
1.5.2 準備就緒的持續集成流水線 10

第2章 構建郵件簡報 12
2.1 引導示例 12
2.1.1 基於問題的學習 12
2.1.2 幫助完善本書 13
2.2 郵件簡報服務應該做什麽 13
2.2.1 捕捉需求:用戶故事 13
2.3 循序漸進,不斷迭代 14
2.3.1 準備開始 15

第3章 註冊新的訂閱者 16
3.1 前期準備工作 16
3.2 選擇一個Web框架 17
3.3 實現第一個端點:健康檢查 17
3.3.1 使用actix-web編寫代碼 18
3.3.2 actix-web應用程序剖析 19
3.3.3 實現健康檢查處理器 24
3.4 第一次集成測試 27
3.4.1 如何對端點進行測試 27
3.4.2 應該將測試放在哪裡 28
3.4.3 改變項目結構以便於測試 30
3.5 實現第一個集成測試 33
3.5.1 優化 36
3.6 重新聚焦 40
3.7 處理HTML表單 40
3.7.1 提煉需求 40
3.7.2 以測試的形式捕捉需求 41
3.7.3 從POST請求中解析表單數據 44
3.8 存儲數據:數據庫 52
3.8.1 選擇數據庫 52
3.8.2 選擇數據庫包 53
3.8.3 帶有副作用的集成測試 55
3.8.4 數據庫初始化 56
3.8.5 編寫第一個查詢 62
3.9 持久化一個新的訂閱者 70
3.9.1 actix-web中的應用程序狀態 70
3.9.2 actix-web工作進程 72
3.9.3 Data提取器 74
3.9.4 INSERT語句 74
3.10 更新測試 78
3.10.1 測試隔離 81
3.11 總結 85

第4章 遙測 86
4.1 未知的未知 86
4.2 可觀測性 87
4.3 日誌 88
4.3.1 log包 89
4.3.2 actix-web的Logger中間件 89
4.3.3 外觀模式 90
4.4 插樁POST /subscriptions 92
4.4.1 與外部系統的交互 93
4.4.2 像用戶一樣思考 94
4.4.3 日誌應當易於關聯 96
4.5 結構化日誌 98
4.5.1 tracing包 99
4.5.2 從log遷移到tracing 99
4.5.3 tracing中的跨度 100
4.5.4 插樁future 102
4.5.5 tracing的Subscriber 104
4.5.6 tracing-subscriber 105
4.5.7 tracing-bunyan-formatter 105
4.5.8 tracing-log 107
4.5.9 刪除未使用的依賴 109
4.5.10 清理初始化流程 109
4.5.11 集成測試中的日誌 112
4.5.12 清理插樁代碼——tracing::instrument 116
4.5.13 保護隱私——secrecy 119
4.5.14 請求ID 121
4.5.15 借力tracing生態系統 124
4.6 總結 124

第5章 上線 125
5.1 我們必須討論部署問題 125
5.2 選擇工具 126
5.2.1 虛擬化:Docker 126
5.2.2 托管:DigitalOcean 127
5.3 應用程序的Dockerfile 127
5.3.1 Dockerfile 127
5.3.2 構建上下文 128
5.3.3 sqlx離線模式 129
5.3.4 運行鏡像 131
5.3.5 網絡 132
5.3.6 層次化配置 133
5.3.7 數據庫連接 138
5.3.8 優化Docker鏡像 139
5.4 部署到DigitalOcean應用平臺 144
5.4.1 安裝 144
5.4.2 應用規範 144
5.4.3 如何使用環境變量註入加密信息 147
5.4.4 連接到DigitalOcean的Postgres實例 149
5.4.5 應用配置中的環境變量 152
5.4.6 最後一步,推送 153

第6章 拒絕無效的訂閱者(第一部分) 155
6.1 需求 156
6.1.1 姓名約束 156
6.1.2 安全約束 156
6.2 第一次實現 158
6.3 漏洞百出的驗證 159
6.4 類型驅動開發 160
6.5 所有權遇見不變量 164
6.5.1 AsRef 167
6.6 panic 169
6.7 Result——將錯誤作為值 171
6.7.1 使解析函數返回Result類型 171
6.8 精確的斷言錯誤:claim 174
6.9 單元測試 175
6.10 處理 Result 177
6.10.1 match 177
6.10.2 “?”操作符 178
6.10.3 400的請求錯誤 179
6.11 電子郵件地址格式 179
6.12 SubscriberEmail類型 180
6.12.1 拆分domain子模塊 180
6.12.2 新類型的框架 181
6.13 屬性測試 184
6.13.1 使用fake生成隨機測試數據 184
6.13.2 quickcheck與proptest 185
6.13.3 quickcheck入門 185
6.13.4 實現Arbitrary特質 186
6.14 請求體驗證 188
6.14.1 使用TryFrom重構 192
6.15 總結 195

第7章 拒絕無效的訂閱者(第二部分) 196
7.1 確認郵件 196
7.1.1 訂閱者的同意 196
7.1.2 確認用戶的流程 197
7.1.3 實現策略 198
7.2 郵件發送組件——EmailClient 198
7.2.1 如何發送電子郵件 198
7.2.2 如何使用reqwest編寫REST客戶端 201
7.2.3 如何測試REST客戶端 208
7.2.4 EmailClient::send_email的初版實現 213
7.2.5 加強正常的測試 221
7.2.6 處理失敗情況 228
7.3 可維護測試套件的骨架和原則 237
7.3.1 為什麽要編寫測試 238
7.3.2 為什麽不編寫測試 238
7.3.3 測試代碼也是代碼 238
7.3.4 測試套件 239
7.3.5 測試發現 240
7.3.6 每個測試文件都是一個包 241
7.3.7 共享測試輔助函數 241
7.3.8 共享啟動邏輯 244
7.3.9 構建API客戶端 252
7.3.10 小結 256
7.4 重新聚焦 256
7.5 零停機部署 257
7.5.1 可靠性 257
7.5.2 部署策略 258
7.6 數據庫遷移 261
7.6.1 狀態存在於應用程序之外 261
7.6.2 部署與遷移 261
7.6.3 多步遷移 262
7.6.4 新的必填字段 262
7.6.5 新表 263
7.7 發送確認郵件 264
7.7.1 固定的電子郵件地址 264
7.7.2 固定的確認鏈接 269
7.7.3 等待確認 272
7.7.4 GET /subscriptions/confirm的骨架 276
7.7.5 整合 278
7.7.6 訂閱令牌 287
7.8 數據庫事務 294
7.8.1 全部成功,或者全部失敗 294
7.8.2 Postgres中的事務 295
7.8.3 sqlx中的事務 295
7.9 總結 299

第8章 錯誤處理 300
8.1 錯誤處理的目的 300
8.1.1 系統內部錯誤 301
8.1.2 系統交互錯誤 303
8.1.3 小結 305
8.2 為操作人員提供錯誤報告 305
8.2.1 跟蹤錯誤的根本原因 308
8.2.2 Error特質 313
8.3 控制流與錯誤處理 316
8.3.1 控制流的分層 316
8.3.2 使用枚舉對錯誤建模 317
8.3.3 只有錯誤類型還不夠 319
8.3.4 使用thiserror減少樣板代碼 323
8.4 防止“大泥球”型的錯誤枚舉 324
8.4.1 使用anyhow擦除錯誤類型 329
8.4.2 使用anyhow還是thiserror 331
8.5 錯誤日誌由誰來記 331
8.6 總結 333

第9章 投遞郵件簡報 334
9.1 用戶故事在變化 334
9.2 不要向未確認的訂閱者發送 335
9.2.1 使用公共API設置狀態 336
9.2.2 scoped mock 337
9.2.3 綠色測試 338
9.3 所有已確認的訂閱者都會收到新內容 339
9.3.1 組合測試輔助函數 339
9.4 實現策略 341
9.5 請求體的內容 341
9.5.1 測試無效輸入 342
9.6 獲取已確認的訂閱者列表 344
9.7 發送郵件簡報 346
9.7.1 context與with_context 347
9.8 驗證存儲的數據 348
9.8.1 責任界限 352
9.8.2 關註編譯器 353
9.8.3 移除樣板代碼 355
9.9 簡單方法的局限性 356
9.10 總結 357

第10章 API的安全性 358
10.1 認證 358
10.1.1 缺點 359
10.1.2 多因素身份驗證 359
10.2 基於密碼的身份驗證 359
10.2.1 基本身份驗證 360
10.2.2 密碼驗證——簡單的方法 365
10.2.3 密碼存儲 368
10.2.4 不要阻塞異步執行器 384
10.2.5 用戶枚舉 390
10.3 這安全嗎 395
10.3.1 傳輸層安全性 395
10.3.2 密碼重置 395
10.3.3 交互類型 395
10.3.4 機器對機器 396
10.3.5 使用瀏覽器的用戶 396
10.3.6 機器對機器(機器代表人) 397
10.4 插曲:下一步計劃 397
10.5 登錄表單 398
10.5.1 提供HTML頁面 398
10.6 登錄 401
10.6.1 HTML表單 401
10.6.2 登錄成功後的重定向 404
10.6.3 處理表單數據 405
10.6.4 上下文錯誤 412
10.7 會話 443
10.7.1 基於會話的身份驗證 443
10.7.2 會話存儲 444
10.7.3 選擇會話存儲 444
10.7.4 actix-session 445
10.7.5 管理儀表板 448
10.8 種子用戶 459
10.8.1 數據庫遷移 459
10.8.2 密碼重置 460
10.9 重構 477
10.9.1 如何實現一個actix-web中間件 478
10.10 總結 484

第11章 容錯的工作流 486
11.1 重溫POST /admin/newsletters 486
11.2 我們的目標 488
11.3 失敗模式 488
11.3.1 無效輸入 488
11.3.2 網絡I/O 489
11.3.3 應用程序崩潰 490
11.3.4 作者的操作 490
11.4 冪等簡介 490
11.4.1 冪等實踐:支付 491
11.4.2 冪等鍵 492
11.4.3 並發請求 493
11.5 測試需求(第一部分) 493
11.6 實現策略 495
11.6.1 有狀態的冪等:保存和重放 495
11.6.2 無狀態的冪等:確定性的鍵生成 495
11.6.3 時間問題有些棘手 495
11.6.4 做出選擇 496
11.7 冪等存儲 496
11.7.1 應該使用哪種數據庫 496
11.7.2 數據庫模式 497
11.8 保存和重放 498
11.8.1 讀取冪等鍵 498
11.8.2 查詢已保存的響應 502
11.8.3 保存響應 505
11.9 並發請求 512
11.9.1 測試需求(第二部分) 512
11.9.2 同步 513
11.10 處理錯誤 520
11.10.1 分佈式事務 522
11.10.2 後向恢復 522
11.10.3 前向恢復 523
11.10.4 異步處理 523
11.11 後記 539