第I部分 入門
第1章 hapi簡介 ··································3
1.1 hapi是什麼 ··································4
1.1.1 hapi的特色 ································6
1.1.2 hapi是哪類框架 ························8
1.2 hapi的組成部分 ························11
1.2.1 服務器 ·····································13
1.2.2 連接 ·········································13
1.2.3 路由 ·········································13
1.2.4 handler ·····································13
1.2.5 插件 ·········································13
1.3 何時應該(不該)使用hapi ······14
1.3.1 何時應該使用hapi ··················14
1.3.2 何時不應該使用hapi ··············15
1.4 hapi的運作方式 ························15
1.4.1 安裝hapi ··································15
1.4.2 創建服務器 ·····························16
1.4.3 添加路由 ·································16
1.4.4 注冊插件 ·································17
1.4.5 運行hapi ··································18
1.5 獲得幫助 ····································18
1.5.1 hapi.js網站 ······························19
1.5.2 Make Me hapi ··························19
1.5.3 GitHub ·····································19
1.5.4 IRC ···········································19
1.5.5 Stack Overflow ························20
目 錄
1.5.6 閱讀代碼 ·································20
1.6 小結 ············································20
第2章 構建API ·································21
2.1 設計API ·····································21
2.1.1 你應該接受這個任務 ·············21
2.1.2 收集需求 ·································22
2.1.3 設計API接口 ·························22
2.2 準備工作 ····································23
2.2.1 工作目錄 ·································23
2.2.2 準備數據庫和樣本數據 ·········23
2.2.3 sqlite3 node模塊 ·····················24
2.3 獲取和搜索食譜 ························25
2.3.1 server.route()介紹 ···················25
2.3.2 路由handler ····························26
2.3.3 接口A:獲取所有食譜 ··········28
2.3.4 接口A:搜索食譜 ··················30
2.3.5 接口B:獲取單一食譜 ··········31
2.4 編寫可維護的代碼 ····················32
2.4.1 模塊化路由 ·····························32
2.4.2 用好server.bind():設置
handler中的上下文 ················33
2.4.3 模塊化handler ························35
2.5 身份驗證 ····································37
2.5.1 模式和策略 ·····························37
2.5.2 實現不記名token身份驗證 ···38
2.5.3 使用用戶憑據 ·························40
XVI hapi.js 實戰
2.6 食譜創建和標星 ························40
2.6.1 測試接口 ·································40
2.6.2 接口C:創建食譜 ··················41
2.7 小結 ············································44
第3 章 構建網站 ·································45
3.1 DinDin 網站 ·······························45
3.1.1 網站的樣子 ·····························45
3.1.2 網站是如何運作的 ·················47
3.1.3 設置 ·········································47
3.2 網頁和靜態內容服務 ················49
3.2.1 靜態文件服務 ·························49
3.2.2 整個目錄服務 ·························51
3.2.3 server.views():使用Handlebars
動態渲染視圖 ·························53
3.2.4 DRY 視圖:布局和片段 ········57
3.3 使用外部API ·····························60
3.3.1 使用Wreck:調用API···········60
3.3.2 動態主頁 ·································62
3.3.3 食譜詳情頁 ·····························62
3.3.4 視圖helper ······························65
3.4 管理登錄和用戶會話 ················67
3.4.1 hapi-auth-cookie 插件 ·············67
3.4.2 錶單 ·········································69
3.4.3 實現登錄 ·································71
3.4.4 創建食譜 ·································75
3.4.5 實現注銷 ·································78
3.5 小結 ············································79
第II 部分 擴展工具箱
第4 章 深入理解路由和handler ·········83
4.1 深入理解路由 ····························83
4.1.1 hapi 的路由:路由的排序和
衝突處理 ·································83
4.1.2 路由方法 ·································84
4.1.3 參數化路徑 ·····························85
4.1.4 hapi 如何選取路由 ··················88
4.2 構建自定義handler ···················90
4.2.1 國際化例子 ·····························91
4.2.2 解析Accept-Language
header ·······································92
4.2.3 第一個實現 ·····························93
4.2.4 再次簡化 ·································94
4.3 服務器方法 ································96
4.4 路由先決條件 ····························99
4.4.1 異步JavaScript 的並發問題 ···99
4.4.2 指定路由先決條件 ·············· 101
4.4.3 使用帶有先決條件的服務器
方法 ······································ 102
4.4.4 多重串行先決條件 ·············· 103
4.4.5 並發先決條件:並行地運行
任務 ······································ 105
4.5 管理文件上傳 ··························107
4.5.1 使用數據輸齣:把文件內容
讀入內存 ······························ 108
4.5.2 使用流輸齣:以流的方式獲取
文件 ······································ 109
4.5.3 使用文件輸齣:把文件存儲到
磁盤 ······································ 110
4.5.4 額外的payload 設置 ·············111
4.4 小結 ·········································· 111
第5 章 理解請求和響應 ····················113
5.1 request 對象和生命周期 ·········· 113
5.1.1 什麼是request 對象 ············· 113
5.1.2 請求的生命周期 ·················· 115
5.1.3 擴展點 ·································· 118
5.1.4 應該使用哪個擴展點? ······ 121
5.2 reply 接口和response 對象 ·····121
5.2.1 什麼是reply 接口? ············ 121
5.2.2 reply() 的有效參數 ··············· 123
XVII
目 錄
5.2.3 response對象 ·······················124
5.2.4 使用流來響應 ······················126
5.3 處理錯誤 ··································128
5.3.1 程序員錯誤和操作錯誤 ······129
5.3.2 HTTP狀態碼 ·······················129
5.3.3 介紹Boom:創建HTTP
友好的錯誤 ··························131
5.3.4 網站友好的HTML錯誤
頁麵 ······································132
5.4 小結 ··········································136
第6章 使用Joi驗證 ························139
6.1 介紹Joi·····································140
6.1.1 Joi的工作方式 ·····················140
6.1.2 一個簡單例子:驗證標量
類型 ······································141
6.1.3 一個更復雜的例子:驗證一個
復閤類型 ······························142
6.2 掌握Joi·····································144
6.2.1 瞭解API ·······························145
6.2.2 Joi.assert()和Joi.validate() ··146
6.2.3 Joi中的類型轉換 ·················146
6.2.4 abortEarly選項 ·····················147
6.2.5 探索Joi錯誤 ························148
6.3 hapi中的驗證 ··························150
6.3.1 使用Joi進行輸入驗證 ········150
6.3.2 驗證payload ·························152
6.3.3 驗證響應 ······························155
6.3.4 使用failAction自定義驗證
響應 ······································156
6.4 整閤:使用hapi和Joi進行Web
錶單驗證 ··································157
6.4.1 如何工作 ······························158
6.4.2 創建骨架 ······························159
6.4.3 創建路由和視圖 ··················160
6.4.4 添加驗證 ······························163
6.4.5 在錶單中渲染錯誤 ··············165
6.4.6 錶單提交成功後的重定嚮 ···167
6.5 小結 ··········································168
第7章 使用插件構建模塊化應用 ·····169
7.1 插件思想 ··································169
7.1.1 插件的定義 ··························171
7.1.2 插件的作用 ··························172
7.1.3 把所有東西放進插件 ··········174
7.1.4 Pingoo應用 ··························174
7.2 創建和加載插件 ······················176
7.2.1 創建插件 ······························176
7.2.2 使用server.register()加載
插件 ······································179
7.2.3 插件依賴 ······························180
7.2.4 使用選項配置插件 ··············182
7.3 使用Glue組閤插件 ················186
7.3.1 什麼是Glue? ·····················186
7.3.2 創建一個清單 ······················187
7.3.3 使用Confidence工具實現智
能配置 ··································190
7.4 插件通信 ··································193
7.4.1 全局的服務器配置 ··············193
7.4.2 通過server.expose()在插件中
對外公開屬性 ······················195
7.4.3 使用事件係統 ······················196
7.5 小結 ··········································200
第8章 充分利用緩存 ·······················201
8.1 客戶端緩存 ······························202
8.1.1 手動設置header ···················203
8.1.2 在配置中設置緩存策略 ······203
8.1.3 重新驗證和ETag ·················204
8.2 介紹Catbox:一個多策略的對象
緩存庫 ······································207
8.2.1 什麼是Catbox ······················208
XVIII hapi.js 實戰
8.2.2 Catbox 客戶端和策略 ·········· 211
8.2.3 Staleness ································ 213
8.2.4 應該用哪個緩存策略? ······ 215
8.3 hapi 應用中的服務器端緩存 ··216
8.3.1 配置客戶端 ·························· 216
8.3.2 使用server.cache() 創建並使用
Catbox 策略 ·························· 217
8.3.3 緩存服務器方法 ·················· 219
8.3.4 使用鍵、分區和段來組織緩存
數據 ······································ 220
8.4 小結 ··········································222
第Ⅲ部分 創建健壯的應用
第9 章 身份驗證和安全 ····················225
9.1 關於身份驗證的深度探討 ······225
9.1.1 hapi 身份驗證概述 ··············· 226
9.1.2 應該選擇哪種身份驗證
模式 ·································228
9.1.3 身份驗證的scope ················ 228
9.1.4 身份驗證模式 ······················ 229
9.2 通過Bell 實現第三方身份
驗證 ··········································231
9.2.1 什麼是第三方身份驗證 ······ 231
9.2.2 Bell 簡介 ······························· 232
9.2.3 將Bell 整閤進hapi 應用 ····· 233
9.3 通過CORS 管理跨域請求 ······240
9.3.1 允許來自任何地方的跨域
請求 ······································ 241
9.3.2 隻接受指定源的訪問 ·········· 243
9.3.3 處理自定義的header ··········· 244
9.3.4 CORS 和憑據(Cookie) ········ 246
9.3.5 CORS 設置的粒度 ··············· 247
9.4 使用Crumb 保護應用免受CSRF
攻擊 ··········································248
9.4.1 通過CSRF 令牌對抗CSRF
攻擊 ······································ 249
9.4.2 通過創建自己的漏洞來理解
CSRF ····································· 250
9.4.3 通過Crumb 保護HTML ····· 253
9.4.4 使用Crumb 保護restful
API ········································ 254
9.5 安全相關的header···················255
9.6 小結 ··········································257
第10 章 使用Lab、Code 和server.inject()
進行測試 ·····························259
10.1 Lab 簡介 ·································259
10.1.1 第一個測試 ························ 260
10.1.2 Lab 作為本地依賴 ············· 261
10.1.3 通過experiments 組織
測試 ·······························262
10.1.4 默認異步執行 ···················· 263
10.1.5 Lab 的語法糖 ····················· 264
10.2 用Code 斷言庫製作斷言 ······265
10.2.1 什麼是Code 斷言庫 ·········· 265
10.2.2 Code 的語法:斷言語句的
結構 ···································· 267
10.3 使用server.inject() 測試hapi
服務 ········································269
10.3.1 為測試準備server ·············· 270
10.3.2 server.inject() 的響應
參數 ···································· 272
10.3.3 使用request payload 進行
測試 ···································· 272
10.3.4 測試需要驗證的路由 ········ 274
10.4 Lab 進階 ·································276
10.4.1 reporter ································ 276
10.4.2 代碼覆蓋率 ························ 278
10.4.3 linting ·································· 278
10.4.4 全局變量泄露 ···················· 279
目 錄 XIX
10.4.5 並行執行測試 ····················279
10.5 使用stub、spies和monkey-patching
測試難以測試的代碼 ············281
10.5.1 monkey-patching介紹 ·······281
10.5.2 使用Sinon的Spy和stub ····284
10.5.3 使用proxyquire ··················286
10.6 小結 ········································288
第11章 投入生産環境及更多相關
內容 ····································291
11.1 hapi的日誌記錄和Good ·······291
11.1.1 hapi中的服務器事件 ·········291
11.1.2 通過request.log()和
server.log()記錄日誌 ·········293
11.1.3 通過Good記錄綫上日誌和
處理監控 ····························296
11.1.4 使用多種reporter實例 ······297
11.2 為路由生成文檔 ····················298
11.2.1 路由的tags、notes和
descriptions ·························299
11.2.2 通過Lout自動生成的
文檔 ····································299
11.3 監控 ········································302
11.3.1 Graphite和StatsD ··············302
11.3.2 通過StatsD度量任何指標 ···303
11.3.3 使用Oppsy獲取hapi的操作
數據 ····································304
11.4 調試 ········································307
11.4.1 不要認為使用console.log()
不好 ····································307
11.4.2 Node debug ·························307
11.4.3 Node Inspector ····················309
11.4.4 通過Poop進行Core
dumps ··································310
11.4.5 使用hapi TV調試實時
請求 ····································312
11.5 部署支持SSL/TLS的應用 ···314
11.5.1 TLS的配置項 ·····················314
11.5.2 在hapi中配置TLS連接 ···315
11.5.3 使用self-signed憑據測試
SSL ······································315
11.5.4 強製HTTPS ·······················317
11.6 小結 ········································319
附錄A Node.js和npm入門 ·············321
附錄B 本書用到的npm包 ···············327
· · · · · · (
收起)