Hapi.js 项目:我们是如何写出高质量路由的
路由是一个网站的骨架,它可以指定用户在浏览器中输入 URL 时将请求发送给哪个页面。在 Hapi.js 项目中,路由扮演着至关重要的角色,它决定着请求将如何被处理以及如何为用户提供反馈。本文将详细介绍如何使用 Hapi.js 来编写高质量的路由,并提供示例代码以便于读者理解和学习。
一、编写可读性高的路由
在编写路由时,我们要注意让代码尽可能地易读易懂。这不仅有助于其他开发人员理解和修改代码,也有助于我们自己在后续开发中更快地定位和解决问题。下面是一些实现可读性路由的方法:
- 使用“层次结构”
按照功能将路由组织成一个合理的、可读性高的结构。一个实用的例子是将路由划分为 CRUD(创建、读取、更新、删除) 操作。例如,在一个 RESTful API 应用中,可以通过以下方式定义路由:
-- -------------------- ---- ------- -------------- ------- ------- ----- ------------------ -------- -------------- --- -------------- ------- ------ ----- ------------------ -------- ------------ --- -------------- ------- ------ ----- ----------------------- -------- --------------- --- -------------- ------- ------ ----- ----------------------- -------- ------------------ --- -------------- ------- --------- ----- ----------------------- -------- ------------------ ---
这样,特定的操作和方法都可以找到归属,让代码结构更易于管理和维护。
- 使用描述性的变量名
使用描述性的变量名能够让代码更加易读。在定义路由时,应该使用清晰明了的名称来描述当前路由的功能。例如,在以下定义中,变量名 resource 和 id 使我们能够更容易地理解路由中的含义:
server.route({ method: 'GET', path: '/api/{resource}/{id}', handler: getResourceByID });
- 只定义实际需要的路由
在项目的初期阶段,你可能会想定义多个路由,以覆盖所有可能的情况。然而,这样做会导致代码的可读性变差。因此,应该只定义需要的路由,以减少对代码质量的影响。
二、路由参数的使用
路由可以使用参数来捕获和处理 URL 参数。在 Hapi.js 中,可以使用 {param} 来指定路由参数。例如:
server.route({ method: 'GET', path: '/users/{id}', handler: getUser });
这里的 {id} 就是该路由的参数。在请求被捕获时,Hapi.js 将会自动解析 URL 并填充参数。可以在路由处理函数中使用 request.params 访问这些参数。例如:
function getUser(request, h) { const id = request.params.id; // Do something with id }
- 处理不正确的参数
在使用路由参数时,应该考虑可能出现的错误情况。例如,当参数不匹配时,处理函数可能会接收到一个 undefined 值。因此,最好在函数中添加一些必要的错误检查,以确保参数有效:
function getUser(request, h) { const id = request.params.id; if (!id) { return h.redirect('/error'); } // Do something with id }
- 使用可选参数和默认值
除了必要参数外,有时候我们还需要一些可选参数。例如,在处理 GET 请求时,可以使用(?)符号指定路由参数是可选的。例如:
-- -------------------- ---- ------- -------------- ------- ------ ----- --------- -------- --------- -------- - -- ---- ------- - ------ ------------------------ - - --- -------- ----------------- -- - ----- ----- - -------------------- -- -- ----- --------- -- -
在这个例子中,如果没有指定 count 参数,将会使用默认值 10。
三、路由处理函数
处理函数是 Hapi.js 中路由的核心部分,它通常是路由的最后一个参数。一个路由处理函数是一个回调函数,在路由被匹配时会被调用。以下是一些处理函数的用例:
- 处理错误
处理函数可以用来处理路由请求期间发生的错误。例如,在尝试访问不存在的资源时,我们可以使用处理函数返回 404 错误:
function getResource(request, h) { if (!request.params.id) { return h.response('Parameter ID is missing').code(404); } }
- 数据转换
处理函数还可以用于数据转换。例如,在从数据库中检索数据时,可以使用处理函数将该数据转换为更好的格式:
async function getResource(request, h) { const data = await db.getResource(request.params.id); const result = { id: data.id, name: data.name }; return result; }
- 实现验证逻辑
处理函数可以用来实现验证逻辑。例如,我们可以使用 Joi 模块对数据进行验证:
-- -------------------- ---- ------- ----- ------ - - ------ -------------------------------- --------- ---------------------------------------------------- -- -------- --------------------- -- - ----- ---------- - ----------------------------- -------- -- ------------------ - ------ --------------------------------------- - -
在这个例子中,如果用户提供的电子邮件地址不是有效的电子邮件格式,处理函数将返回一个 400 错误。
四、路由选项
路由选项是可选的,并且可以包含任何路由的属性。下面列举其中几个:
- 验证方法
路由选项可以定义一个 validate 方法,该方法将在请求到达处理函数之前被调用。这通常用于验证请求的有效性。该方法应该返回一个错误或一个有效的值。如果返回一个错误,则将返回一个 HTTP 400 错误响应。
-- -------------------- ---- ------- ----- ------ - - ------ -------------------------------- --------- ---------------------------------------------------- -- -------- --------------------- -- - ----- ---------- - ----------------------------- -------- -- ------------------ - ------ --------------------------------------- - -
- 描述
描述选项允许您为路由添加描述信息。这可以用于生成 API 文档或提供其他形式的说明。
-- -------------------- ---- ------- -------------- ------- ------ ----- --------- -------- --------- -- -- - ------ ------ -------- -- -------- - ------------ ----- ----- -- --- ------ - --
- 标签
标签选项用于将路由标记为特定类型的路由。例如,我们可以使用标签“api”将路由归类为 API。
server.route({ method: 'POST', path: '/api/users', handler: createUser, options: { tags: ['api'] } })
这样,就可以通过标签过滤 API 路由。
总结:
本文介绍了如何编写高质量、可读性高的 Hapi.js 路由,并提供了示例代码。通过使用 路由参数、路由描述、路由标签 以及 路由处理函数,你可以轻松地构建出强大的应用程序。通过引入更多的验证、数据转换和错误处理,可以最小化错误和时间浪费,使项目更加健壮和高效。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/65022a2c95b1f8cacdf945bc