常用插件 #
一、核心插件 #
1.1 @hapi/inert #
静态文件服务插件:
bash
npm install @hapi/inert
javascript
const Inert = require('@hapi/inert');
await server.register(Inert);
server.route({
method: 'GET',
path: '/static/{param*}',
handler: {
directory: {
path: './public',
listing: true
}
}
});
server.route({
method: 'GET',
path: '/download',
handler: (request, h) => {
return h.file('./files/document.pdf', {
mode: 'attachment'
});
}
});
1.2 @hapi/vision #
模板引擎支持插件:
bash
npm install @hapi/vision ejs
javascript
const Vision = require('@hapi/vision');
await server.register(Vision);
server.views({
engines: {
ejs: require('ejs')
},
path: './views',
layout: true
});
server.route({
method: 'GET',
path: '/page',
handler: (request, h) => {
return h.view('index', {
title: 'Hello',
message: 'Welcome!'
});
}
});
1.3 @hapi/cookie #
Cookie认证插件:
bash
npm install @hapi/cookie
javascript
const Cookie = require('@hapi/cookie');
await server.register(Cookie);
server.auth.strategy('session', 'cookie', {
cookie: {
name: 'session',
password: 'password-should-be-32-characters',
isSecure: false
},
redirectTo: '/login',
validateFunc: async (request, session) => {
const user = await User.findById(session.id);
if (!user) {
return { valid: false };
}
return { valid: true, credentials: user };
}
});
server.auth.default('session');
1.4 @hapi/jwt #
JWT认证插件:
bash
npm install @hapi/jwt
javascript
const Jwt = require('@hapi/jwt');
await server.register(Jwt);
server.auth.strategy('jwt', 'jwt', {
keys: 'your-secret-key',
verify: {
aud: 'urn:audience:test',
iss: 'urn:issuer:test',
sub: false,
nbf: true,
exp: true,
maxAgeSec: 14400
},
validate: (artifacts, request, h) => {
return {
isValid: true,
credentials: { user: artifacts.decoded.payload.user }
};
}
});
server.auth.default('jwt');
二、开发插件 #
2.1 @hapi/good #
日志插件:
bash
npm install @hapi/good @hapi/good-console @hapi/good-squeeze
javascript
const Good = require('@hapi/good');
await server.register({
plugin: Good,
options: {
ops: {
interval: 1000
},
reporters: {
console: [
{
module: '@hapi/good-squeeze',
name: 'Squeeze',
args: [{ log: '*', response: '*' }]
},
{
module: '@hapi/good-console'
},
'stdout'
]
}
}
});
2.2 @hapi/bell #
第三方OAuth认证插件:
bash
npm install @hapi/bell
javascript
const Bell = require('@hapi/bell');
await server.register(Bell);
server.auth.strategy('github', 'bell', {
provider: 'github',
password: 'cookie-encryption-password',
clientId: 'your-github-client-id',
clientSecret: 'your-github-client-secret',
isSecure: false
});
server.route({
method: ['GET', 'POST'],
path: '/login/github',
options: {
auth: 'github',
handler: (request, h) => {
if (!request.auth.isAuthenticated) {
return 'Authentication failed';
}
return request.auth.credentials;
}
}
});
2.3 @hapi/swagger #
API文档插件:
bash
npm install @hapi/swagger @hapi/inert @hapi/vision
javascript
const Inert = require('@hapi/inert');
const Vision = require('@hapi/vision');
const HapiSwagger = require('hapi-swagger');
const swaggerOptions = {
info: {
title: 'API Documentation',
version: '1.0.0'
}
};
await server.register([
Inert,
Vision,
{
plugin: HapiSwagger,
options: swaggerOptions
}
]);
server.route({
method: 'GET',
path: '/users',
options: {
description: 'Get all users',
tags: ['api'],
handler: (request, h) => {
return { users: [] };
}
}
});
三、安全插件 #
3.1 @hapi/crumb #
CSRF防护插件:
bash
npm install @hapi/crumb
javascript
const Crumb = require('@hapi/crumb');
await server.register({
plugin: Crumb,
options: {
cookieOptions: {
isSecure: false
}
}
});
server.route({
method: 'POST',
path: '/form',
options: {
plugins: {
crumb: true
}
},
handler: (request, h) => {
return { message: 'Form submitted' };
}
});
3.2 @hapi/scooter #
User Agent解析插件:
bash
npm install @hapi/scooter
javascript
const Scooter = require('@hapi/scooter');
await server.register(Scooter);
server.route({
method: 'GET',
path: '/browser',
handler: (request, h) => {
return {
browser: request.plugins.scooter.browser,
os: request.plugins.scooter.os
};
}
});
四、数据库插件 #
4.1 hapi-mongodb #
MongoDB集成插件:
bash
npm install hapi-mongodb
javascript
await server.register({
plugin: require('hapi-mongodb'),
options: {
url: 'mongodb://localhost:27017/mydb',
settings: {
poolSize: 10
},
decorate: true
}
});
server.route({
method: 'GET',
path: '/users',
handler: async (request, h) => {
const db = request.mongo.db;
const users = await db.collection('users').find({}).toArray();
return users;
}
});
4.2 hapi-sequelizejs #
Sequelize ORM插件:
bash
npm install hapi-sequelizejs sequelize pg
javascript
await server.register({
plugin: require('hapi-sequelizejs'),
options: [
{
name: 'mydb',
models: ['./models/**/*.js'],
sequelize: new Sequelize('mydb', 'user', 'pass', {
dialect: 'postgres'
})
}
]
});
server.route({
method: 'GET',
path: '/users',
handler: async (request, h) => {
const { User } = request.server.models().mydb;
return await User.findAll();
}
});
五、缓存插件 #
5.1 @hapi/catbox-redis #
Redis缓存插件:
bash
npm install @hapi/catbox-redis
javascript
const CatboxRedis = require('@hapi/catbox-redis');
const server = Hapi.server({
port: 3000,
cache: [
{
name: 'redis-cache',
provider: {
constructor: CatboxRedis,
options: {
partition: 'my-app',
host: 'localhost',
port: 6379
}
}
}
]
});
server.method('getUser', async (id) => {
return await User.findById(id);
}, {
cache: {
cache: 'redis-cache',
expiresIn: 60 * 1000,
generateTimeout: 100
}
});
六、验证插件 #
6.1 @hapi/joi #
数据验证库:
bash
npm install @hapi/joi
javascript
const Joi = require('@hapi/joi');
server.route({
method: 'POST',
path: '/users',
options: {
validate: {
payload: Joi.object({
name: Joi.string().min(2).max(50).required(),
email: Joi.string().email().required(),
age: Joi.number().integer().min(0).max(120)
})
}
},
handler: (request, h) => {
return request.payload;
}
});
七、错误处理插件 #
7.1 @hapi/boom #
HTTP错误处理:
bash
npm install @hapi/boom
javascript
const Boom = require('@hapi/boom');
server.route({
method: 'GET',
path: '/users/{id}',
handler: async (request, h) => {
const user = await User.findById(request.params.id);
if (!user) {
throw Boom.notFound('User not found');
}
if (!user.active) {
throw Boom.forbidden('User is inactive');
}
return user;
}
});
八、HTTP客户端插件 #
8.1 @hapi/wreck #
HTTP客户端:
bash
npm install @hapi/wreck
javascript
const Wreck = require('@hapi/wreck');
server.route({
method: 'GET',
path: '/proxy',
handler: async (request, h) => {
const { payload } = await Wreck.get('https://api.example.com/data');
return payload;
}
});
server.route({
method: 'POST',
path: '/forward',
handler: async (request, h) => {
const { payload } = await Wreck.post('https://api.example.com/data', {
payload: request.payload
});
return payload;
}
});
九、文件上传插件 #
9.1 hapi-payload #
处理文件上传:
javascript
server.route({
method: 'POST',
path: '/upload',
options: {
payload: {
output: 'file',
parse: true,
maxBytes: 10 * 1024 * 1024,
multipart: true
}
},
handler: (request, h) => {
const file = request.payload.file;
return {
filename: file.filename,
headers: file.headers,
bytes: file.bytes
};
}
});
十、插件组合示例 #
10.1 完整配置 #
javascript
const Hapi = require('@hapi/hapi');
const Inert = require('@hapi/inert');
const Vision = require('@hapi/vision');
const Jwt = require('@hapi/jwt');
const Boom = require('@hapi/boom');
const Joi = require('@hapi/joi');
const init = async () => {
const server = Hapi.server({ port: 3000 });
await server.register([
Inert,
Vision,
Jwt
]);
server.auth.strategy('jwt', 'jwt', {
keys: process.env.JWT_SECRET,
verify: {
aud: false,
iss: false,
sub: false,
nbf: true,
exp: true
},
validate: (artifacts, request, h) => {
return {
isValid: true,
credentials: artifacts.decoded.payload
};
}
});
server.route([
{
method: 'GET',
path: '/static/{param*}',
handler: {
directory: {
path: './public'
}
}
},
{
method: 'GET',
path: '/profile',
options: {
auth: 'jwt'
},
handler: (request, h) => {
return request.auth.credentials;
}
}
]);
await server.start();
console.log('Server running on %s', server.info.uri);
};
init();
十一、总结 #
常用插件列表:
| 插件 | 用途 |
|---|---|
| @hapi/inert | 静态文件服务 |
| @hapi/vision | 模板引擎 |
| @hapi/cookie | Cookie认证 |
| @hapi/jwt | JWT认证 |
| @hapi/good | 日志记录 |
| @hapi/bell | OAuth认证 |
| @hapi/joi | 数据验证 |
| @hapi/boom | 错误处理 |
| @hapi/wreck | HTTP客户端 |
下一步,让我们深入学习请求与响应!
最后更新:2026-03-28