一、Hapi.js 基礎
1. 核心概念
-
企業級Node.js框架:由Walmart團隊創建,現由社區維護
-
配置驅動:強調聲明式配置而非中間件
-
插件架構:高度模塊化設計
-
安全優先:內置安全最佳實踐
-
豐富的生態系統:官方維護核心插件
2. 核心組件
-
Server:應用實例
-
Route:路由配置
-
Plugin:功能模塊
-
Request/Response:請求/響應生命周期
-
Validation:內置輸入驗證
二、服務器與路由
1. 服務器配置
const Hapi = require('@hapi/hapi');const init = async () => {const server = Hapi.server({port: 3000,host: 'localhost',routes: {cors: true,validate: {failAction: 'log' // 驗證失敗時的行為}}});
};
2. 路由系統
server.route({method: 'GET',path: '/',handler: (request, h) => {return 'Hello World!';},options: {description: '首頁路由',notes: '返回歡迎信息',tags: ['api']}
});
三、請求生命周期
1. 生命周期階段
-
onRequest?- 收到原始請求
-
onPreAuth?- 認證前
-
onPostAuth?- 認證后
-
onPreHandler?- 路由處理器前
-
onPostHandler?- 路由處理器后
-
onPreResponse?- 發送響應前
-
onPostResponse?- 響應發送后
2. 擴展點
server.ext('onPreHandler', (request, h) => {console.log('在路由處理器前執行');return h.continue;
});
四、插件系統
1. 插件基礎
const myPlugin = {name: 'myPlugin',version: '1.0.0',register: async (server, options) => {server.route({method: 'GET',path: '/plugin-route',handler: () => '來自插件'});}
};await server.register({plugin: myPlugin,options: { /* 配置選項 */ }
});
2. 常用官方插件
-
@hapi/vision:模板渲染
-
@hapi/inert:靜態文件服務
-
@hapi/joi:數據驗證
-
@hapi/basic:基本認證
-
@hapi/boom:HTTP友好錯誤
五、輸入驗證
1. Joi驗證
const Joi = require('@hapi/joi');server.route({method: 'POST',path: '/user',handler: (request) => {return `Created ${request.payload.name}`;},options: {validate: {payload: Joi.object({name: Joi.string().min(3).required(),age: Joi.number().integer().min(0)})}}
});
2. 驗證類型
-
params:路徑參數
-
query:查詢字符串
-
payload:請求體
-
headers:請求頭
-
failAction:驗證失敗處理策略
六、認證與授權
1. 認證策略
const basicAuth = require('@hapi/basic');await server.register(basicAuth);server.auth.strategy('simple', 'basic', { validate: async (request, username, password) => {// 驗證邏輯return { isValid: true, credentials: { user } };}
});server.auth.default('simple'); // 設置默認策略
2. 認證模式
-
basic:基本認證
-
cookie:基于cookie
-
jwt:JSON Web Token
-
oauth:OAuth集成
七、緩存與性能
1. 服務器緩存
const Catbox = require('@hapi/catbox');
const Memory = require('@hapi/catbox-memory');const cache = new Catbox.Client(Memory, {partition: 'app-cache'
});await server.register({plugin: require('@hapi/catbox'),options: { client: cache }
});
2. 客戶端緩存
server.route({method: 'GET',path: '/cached',handler: (request) => {return '緩存內容';},options: {cache: {expiresIn: 30 * 1000,privacy: 'private'}}
});
八、測試與調試
1. 測試工具
-
@hapi/lab:測試框架
-
@hapi/code:斷言庫
-
server.inject():模擬HTTP請求
2. 測試示例
const Lab = require('@hapi/lab');
const { expect } = require('@hapi/code');
const { after, before, describe, it } = exports.lab = Lab.script();describe('GET /', () => {it('響應200狀態碼', async () => {const res = await server.inject({method: 'GET',url: '/'});expect(res.statusCode).to.equal(200);});
});
九、生產部署
1. 最佳實踐
-
使用PM2或nodemon進行進程管理
-
配置反向代理(Nginx/Apache)
-
設置環境變量管理配置
-
實現日志輪轉
-
啟用HTTPS
2. 性能優化
-
使用Clustering
-
合理配置緩存策略
-
優化數據庫查詢
-
啟用壓縮中間件
-
監控內存使用
十、生態系統
1. 常用插件
插件名稱 | 用途 |
---|---|
hapi-swagger | API文檔生成 |
hapi-pino | 高性能日志 |
hapi-auth-jwt2 | JWT認證 |
hapi-rate-limit | 速率限制 |
hapi-qs | 查詢字符串解析 |
2. 相關工具
-
Glue:組合服務器配置
-
Schwifty:數據庫集成
-
Hapi-react-views:React服務端渲染
-
Hapi-dev-errors:開發錯誤處理
十一、與Express對比
特性 | Hapi | Express |
---|---|---|
設計理念 | 配置驅動 | 中間件驅動 |
路由系統 | 聲明式配置 | 鏈式調用 |
驗證 | 內置Joi | 需要中間件 |
插件系統 | 核心特性 | 非官方標準 |
學習曲線 | 較陡峭 | 較平緩 |
適用場景 | 企業級應用 | 快速原型 |
Hapi.js特別適合構建需要嚴格架構、良好可維護性和企業級特性的API服務。其強大的插件系統和內置功能減少了對外部中間件的依賴,使應用更加一致和可預測。