Hapi 是一款非常流行的 Node.js 框架,其具有出色的插件系统和构建 API 的能力。在使用 Hapi 构建一款应用时,路由和控制器是非常重要的组成部分。本文将详细介绍 Hapi 路由和控制器的使用。
路由
路由是管理 URL 路径、HTTP 动词和处理程序之间关系的机制。在 Hapi 中定义路由可以使用 route 的配置项。
以下是一个简单的路由示例:
server.route({ method: 'GET', path: '/', handler: (request, h) => { return 'Hello World!'; } });
这个路由将会监听根 URL,使用 GET 请求,并返回字符串 Hello World!
。
路由参数
在一些情况下,我们需要使用 URL 参数以优雅地处理动态路由。Hapi 支持三种不同类型的动态路由参数:path,query 和 payload。
Path 参数
Path 参数是从 URL 中提取的参数,可以使用花括号括起来,如下所示:
server.route({ method: 'GET', path: '/user/{id}', handler: (request, h) => { const id = request.params.id; return `Hi, user ${id}!`; } });
在这个例子中,我们定义了一个 path 参数 id
,可以通过访问 /user/1
来获取用户 1 的信息。
Query 参数
Query 参数是从 URL 中提取的参数,位于问号字符 (?
) 之后,并且以 key=value
的形式存储。在 Hapi 中可以通过 request.query
来得到所有的 query 参数。
server.route({ method: 'GET', path: '/user', handler: (request, h) => { const query = request.query; const id = query.id; return `Hi, user ${id}!`; } });
在这个例子中,我们定义了一个 query 参数 id
,可以通过访问 /user?id=1
来获取用户 1 的信息,注意,question mark(?) 后的查询参数是由 hapi router 的解析器解析的。
Payload 参数
除了从 URL 中提取参数,我们还可以从请求的负载中提取参数。Hapi 通过将负载解析为 JSON 对象(如果存在)来获取这些参数。
server.route({ method: 'POST', path: '/user', handler: (request, h) => { const data = request.payload; const name = data.name; const age = data.age; return `Hi, my name is ${name}. I am ${age} years old.`; } });
在这个例子中,我们定义了一个负载参数 name
和 age
,可以通过访问 POST /user
并提供 JSON 负载数据 {"name": "Zhang San", "age": 18}
来创建一个新用户。
路由装饰器
Hapi 也支持使用路由装饰器来定义路由,这是一种更加优雅的方式。框架提供了多个装饰器,包括 @route
、@GET
、@POST
等。这里以 @route
装饰器为例:
@route({ method: 'GET', path: '/user/{id}', }) function getUser(request, h) { const id = request.params.id; return `Hi, user ${id}!`; }
在这个例子中,我们定义了一个方法 getUser
,它使用了 @route
装饰器表示这是一个路由,并且定义了请求方法为 GET,请求路径为 /user/{id}
。当接收到 /user/1
的请求时,会触发 getUser
方法并返回 Hi, user 1!
。
路由拦截器
在路由被处理之前或之后,我们可能需要执行一些任务。这些任务可以通过在路由上注册预处理器和后处理器来实现。在 Hapi 中,我们可以定义一个或多个预处理器和后处理器。例如:
server.route({ method: 'POST', path: '/user', handler: (request, h) => { const data = request.payload; const name = data.name; const age = data.age; return `Hi, my name is ${name}. I am ${age} years old.`; }, config: { pre: [ { method: logRequest, assign: 'log' } ], post: [ { method: logResponse, assign: 'log' } ] } }); function logRequest(request, h) { console.log('Received request:', request.payload); return h.continue; } function logResponse(request, h) { console.log('Sending response:', request.response.source); return h.continue; }
在这个例子中,我们定义了两个拦截器:logRequest
和 logResponse
。当接收到 POST /user
的请求时,首先触发 logRequest
方法,它将请求数据打印到控制台。接着处理请求,并最终触发 logResponse
方法,它将响应数据打印到控制台。
控制器
控制器是处理业务逻辑的组件,通常与路由分离,可以让代码更加模块化、易于测试和维护。在 Hapi 中,我们可以将处理函数定义为控制器。
下面是一个简单的控制器示例:
class UserController { async getUser(request, h) { const id = request.params.id; const user = await getUserById(id); return user; } } server.route({ method: 'GET', path: '/user/{id}', handler: UserController.getUser });
在这个例子中,我们定义了一个 UserController
控制器,其中定义了一个 getUser
方法,它将根据传入的 id
查询用户信息并返回。我们在路由上使用 UserController.getUser
方法来处理 /user/{id}
的 GET 请求。
使用控制器有助于管理和扩展路由和业务逻辑处理代码,使代码结构更加清晰和模块化。
总结
Hapi 提供了很多先进的功能来管理路由、处理程序和中间件。本文详细介绍了 Hapi 的路由和控制器的使用,包括路由参数、路由装饰器、路由拦截器和控制器等。
通过正确使用路由和控制器,可以构建出更加健壮、可扩展和易于维护的应用程序。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a215a1add4f0e0ffa26d0c