一、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服务。其强大的插件系统和内置功能减少了对外部中间件的依赖,使应用更加一致和可预测。