Hapi 是一个流行的 Node.js Web 框架,它提供了一种灵活的方式来构建 Web 应用程序。其中一个重要的功能是 Pre Handlers,它们可以在路由处理程序之前运行,用于预处理请求和响应。在本文中,我们将深入探讨 Hapi 框架中 Pre Handlers 的使用方法和指南。
Pre Handlers 是什么?
在 Hapi 中,Pre Handlers 是一种函数,它们在路由处理程序之前运行,并且可以访问请求和响应对象。Pre Handlers 可以用于执行各种任务,例如身份验证、数据验证、日志记录等。它们可以返回一个值,这个值将作为请求的新有效载荷传递给路由处理程序。
Pre Handlers 以数组的形式定义在路由配置对象中,如下所示:
// javascriptcn.com 代码示例 const Hapi = require('@hapi/hapi'); const server = Hapi.server({ port: 3000, host: 'localhost' }); const routes = [ { method: 'GET', path: '/users', handler: (request, h) => { return 'Hello, world!'; }, options: { pre: [ { method: async function(request, h) { // Do something return request.payload; }, assign: 'payload' } ] } } ]; server.route(routes); (async () => { await server.start(); console.log(`Server running at: ${server.info.uri}`); })();
在上面的代码中,我们定义了一个路由对象,其中包含一个 GET 请求处理程序和一个 Pre Handler。Pre Handler 是一个异步函数,它返回请求有效载荷。Pre Handler 函数的结果将赋值给 request.pre.payload
,并在请求处理程序中使用。
Pre Handlers 的使用场景
Pre Handlers 可以用于许多不同的场景,例如:
- 身份验证:在处理请求之前,验证用户的身份,以确保他们具有访问权限。
- 数据验证:验证请求有效载荷的格式和内容,以确保它们符合预期。
- 缓存控制:在处理请求之前,检查缓存是否存在,如果存在,则返回缓存的响应。
- 日志记录:在处理请求之前,记录请求和响应的详细信息,以便进行故障排除和性能分析。
Pre Handlers 的使用指南
以下是使用 Pre Handlers 的一些最佳实践:
1. 使用 Pre Handlers 进行身份验证
Pre Handlers 可以用于验证用户的身份,并根据需要拒绝请求。例如,我们可以使用 Pre Handlers 来验证用户是否具有访问特定路由的权限。下面是一个示例:
// javascriptcn.com 代码示例 const Hapi = require('@hapi/hapi'); const server = Hapi.server({ port: 3000, host: 'localhost' }); const routes = [ { method: 'GET', path: '/users', handler: (request, h) => { return 'Hello, world!'; }, options: { pre: [ { method: async function(request, h) { const user = await getUserFromToken(request.headers.authorization); if (!user) { throw Boom.unauthorized('Invalid token'); } return user; }, assign: 'user' } ] } } ]; server.route(routes); (async () => { await server.start(); console.log(`Server running at: ${server.info.uri}`); })();
在上面的代码中,我们定义了一个 Pre Handler,它使用 JWT 令牌验证用户的身份。如果令牌无效,则抛出 Boom.unauthorized
错误。如果令牌有效,则返回用户对象,以便在请求处理程序中使用。
2. 使用 Pre Handlers 进行数据验证
Pre Handlers 可以用于验证请求有效载荷的格式和内容。例如,我们可以使用 Pre Handlers 来验证请求体中的数据是否符合预期。下面是一个示例:
// javascriptcn.com 代码示例 const Hapi = require('@hapi/hapi'); const server = Hapi.server({ port: 3000, host: 'localhost' }); const routes = [ { method: 'POST', path: '/users', handler: (request, h) => { return 'User created successfully!'; }, options: { pre: [ { method: async function(request, h) { const schema = Joi.object({ username: Joi.string().required(), email: Joi.string().email().required(), password: Joi.string().min(6).required() }); const { error, value } = schema.validate(request.payload); if (error) { throw Boom.badRequest(error.details[0].message); } return value; }, assign: 'user' } ] } } ]; server.route(routes); (async () => { await server.start(); console.log(`Server running at: ${server.info.uri}`); })();
在上面的代码中,我们定义了一个 Pre Handler,它使用 Joi 模块验证请求体中的数据。如果数据无效,则抛出 Boom.badRequest
错误。如果数据有效,则返回数据,以便在请求处理程序中使用。
3. 使用 Pre Handlers 进行缓存控制
Pre Handlers 可以用于检查缓存是否存在,并在需要时返回缓存的响应。例如,我们可以使用 Pre Handlers 来检查 Redis 缓存中是否存在请求的数据。下面是一个示例:
// javascriptcn.com 代码示例 const Hapi = require('@hapi/hapi'); const Redis = require('ioredis'); const redis = new Redis(); const server = Hapi.server({ port: 3000, host: 'localhost' }); const routes = [ { method: 'GET', path: '/users/{id}', handler: (request, h) => { return `User ${request.params.id}`; }, options: { pre: [ { method: async function(request, h) { const cacheKey = `user:${request.params.id}`; const cachedData = await redis.get(cacheKey); if (cachedData) { return h.response(cachedData).header('X-Cache', 'Hit'); } return null; } } ] } } ]; server.route(routes); (async () => { await server.start(); console.log(`Server running at: ${server.info.uri}`); })();
在上面的代码中,我们定义了一个 Pre Handler,它检查 Redis 缓存中是否存在用户数据。如果数据存在,则返回缓存的数据,并在响应头中添加 X-Cache: Hit
标记。如果数据不存在,则返回 null。
4. 使用 Pre Handlers 进行日志记录
Pre Handlers 可以用于记录请求和响应的详细信息,以便进行故障排除和性能分析。例如,我们可以使用 Pre Handlers 来记录请求和响应的时间戳和状态码。下面是一个示例:
// javascriptcn.com 代码示例 const Hapi = require('@hapi/hapi'); const Pino = require('hapi-pino'); const server = Hapi.server({ port: 3000, host: 'localhost' }); const routes = [ { method: 'GET', path: '/users', handler: (request, h) => { return 'Hello, world!'; }, options: { pre: [ { method: async function(request, h) { request.logger.info({ event: 'request' }); return null; } } ] } } ]; server.register({ plugin: Pino, options: { prettyPrint: true } }); server.route(routes); (async () => { await server.start(); console.log(`Server running at: ${server.info.uri}`); })();
在上面的代码中,我们定义了一个 Pre Handler,它使用 Pino 日志插件记录请求的时间戳和响应状态码。我们还在服务器上注册了 Pino 插件,以便记录日志。
总结
Pre Handlers 是 Hapi 框架中的一个重要功能,它们可以用于预处理请求和响应。在本文中,我们深入探讨了 Pre Handlers 的使用方法和指南,并提供了一些示例代码。我们希望这篇文章能够帮助您更好地使用 Hapi 框架构建 Web 应用程序。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/657fd386d2f5e1655dab173e