egg路由的定义、配置及使用方法有哪些?

在Web开发中,路由是连接用户请求与业务逻辑的核心桥梁,它负责将不同URL路径和HTTP方法映射到对应的处理函数,Egg.js作为阿里巴巴开源的企业级Node.js框架,其路由系统继承了Koa的简洁性,同时通过约定优于配置的理念,提供了高度可维护、可扩展的路由管理能力,本文将围绕Egg.js的路由机制展开,从基础定义到高级特性,详细解析其设计思路与使用方法。

egg路由

路由基础:定义与映射

Egg.js中的路由通过app/router.js文件进行集中管理,开发者可以通过app.router或直接在文件中使用app.method()(如app.getapp.post)来定义路由规则,其核心是将HTTP请求的路径(path)和方法(method)与控制器(Controller)中的方法绑定,实现请求的精准分发。

定义一个GET请求的路由,用于获取用户信息:

// app/router.js
module.exports = app => {
  const { router, controller } = app;
  router.get('/users/:id', controller.user.getUser); // 路径参数:id
};

这里,/users/:id是一个带路径参数的路由,id表示动态参数,当请求/users/123时,参数id的值为"123",最终请求会交由controller.user.getUser方法处理,Egg.js支持所有标准HTTP方法,包括getpostputdeletepatch等,方法名与HTTP方法一一对应,语义清晰。

路由参数:灵活获取请求数据

Egg.js路由支持多种参数类型,包括路径参数、查询参数和请求体参数,满足不同场景下的数据获取需求。

路径参数

路径参数通过在路由路径中定义,如/users/:id中的id,在控制器中,可通过ctx.params获取所有路径参数组成的对象,

// app/controller/user.js
exports.getUser = async ctx => {
  const { id } = ctx.params; // 获取路径参数id
  ctx.body = { userId: id };
};

查询参数

查询参数是URL中后的键值对,如/users?page=1&size=10,通过ctx.query可获取解析后的查询参数对象:

exports.listUser = async ctx => {
  const { page = 1, size = 10 } = ctx.query; // 默认值处理
  ctx.body = { page, size };
};

请求体参数

对于POST、PUT等携带请求体的方法,Egg.js通过中间件bodyParser自动解析请求体(支持JSON、form-data、x-www-form-urlencoded等格式),开发者可通过ctx.request.body获取数据:

exports.createUser = async ctx => {
  const { name, age } = ctx.request.body;
  ctx.body = { name, age };
};

为更直观地对比参数类型,以下表格总结了不同参数的获取方式:

参数类型 获取方式 示例URL 控制器中获取方式
路径参数 ctx.params /users/123 ctx.params.id
查询参数 ctx.query /users?page=1 ctx.query.page
请求体参数 ctx.request.body POST { "name": "Tom" } ctx.request.body.name

路由分组:模块化管理

当项目规模扩大时,路由数量会急剧增加,Egg.js通过路由分组(app.group)实现模块化管理,避免重复前缀和中间件逻辑,将所有用户相关的路由统一管理:

egg路由

// app/router.js
module.exports = app => {
  const { router, controller } = app;
  const userRouter = router.group('/api/v1/user'); // 定义分组前缀
  userRouter.get('/:id', controller.user.getUser); // 实际路径:/api/v1/user/:id
  userRouter.post('/', controller.user.createUser);
};

分组不仅支持统一前缀,还能批量绑定中间件,为用户分组添加权限校验中间件:

const authMiddleware = app.middleware.auth(); // 自定义权限中间件
userRouter.use(authMiddleware); // 分组内所有路由生效

中间件:增强路由能力

中间件是Egg.js路由的核心扩展机制,它可以在请求到达控制器前或响应返回后执行预处理逻辑,如日志记录、权限校验、数据校验等,Egg.js支持路由级中间件,即中间件仅对当前路由或分组路由生效。

路由级中间件

在定义路由时,通过middleware选项指定中间件:

router.get('/admin', app.middleware.auth(), controller.admin.index);

这里,app.middleware.auth()是一个自定义的权限校验中间件,只有通过校验的请求才能访问/admin路由。

中间件执行顺序

中间件的执行遵循“洋葱模型”,即请求进入时按定义顺序执行,离开时按逆序执行。

router.get('/test', middlewareA, middlewareB, controller.test);

执行流程为:请求进入 → middlewareA预处理 → middlewareB预处理 → controller.test处理 → middlewareB后处理 → middlewareA后处理 → 返回响应。

动态路由与通配符

Egg.js支持动态路由和通配符,满足复杂路径匹配需求。

正则表达式参数

通过在路径参数中定义正则表达式,限制参数格式,限制id必须为数字:

router.get('/users/:id(\d+)', controller.user.getUser); // 仅匹配数字id

请求/users/abc将返回404,而/users/123正常匹配。

egg路由

通配符路由

使用匹配任意路径,常用于404处理或动态代理:

router.all('*', controller.notFound); // 匹配所有未定义的路由

错误处理:健壮的路由异常捕获

路由处理过程中可能抛出异常(如参数错误、数据库错误),Egg.js通过全局异常中间件统一捕获,同时支持路由级错误处理,在控制器中手动抛出错误:

exports.getUser = async ctx => {
  const { id } = ctx.params;
  if (!id) {
    throw new Error('userId is required'); // 抛出异常
  }
  ctx.body = { userId: id };
};

全局异常中间件(如app/middleware/error.js)会捕获此类异常并返回统一格式的错误响应,避免直接暴露错误信息给用户。

高级特性:多应用与控制器关联

多应用路由

在多应用架构(如通过egg-plugin-multiapp插件)中,每个子应用可独立管理路由,通过app.subapp访问子应用路由,实现模块解耦。

控制器关联

Egg.js支持将路由与控制器类直接关联,减少手动绑定的代码量,通过app/controller目录下的文件结构,框架会自动将路由映射到对应控制器方法。app/controller/user.js中的getUser方法,可通过router.get('/user', 'user.getUser')绑定,无需引入controller对象。

Egg.js的路由系统通过简洁的API设计、灵活的参数处理、强大的分组与中间件机制,为开发者提供了高效、可维护的路由管理方案,无论是小型项目还是大型企业级应用,其“约定优于配置”的理念都能帮助开发者快速构建结构清晰、扩展性强的Web服务,掌握Egg.js路由的核心特性,不仅能提升开发效率,更能为后续的代码维护和迭代奠定坚实基础。

相关问答FAQs

Q1:Egg.js中如何实现路由级别的权限控制?
A:可通过路由中间件实现权限控制,首先自定义一个权限校验中间件(如app/middleware/auth.js),在中间件中根据用户角色或权限判断是否放行,然后在路由或路由分组中绑定该中间件。

// app/middleware/auth.js
module.exports = () => {
  return async (ctx, next) => {
    const token = ctx.header.authorization;
    if (!token) {
      ctx.throw(401, 'Unauthorized');
    }
    // 校验token逻辑...
    await next();
  };
};
// app/router.js
router.get('/admin', app.middleware.auth(), controller.admin.index);

Q2:Egg.js路由分组时如何统一处理跨域问题?
A:可自定义跨域中间件,并在路由分组中批量绑定,定义app/middleware/cors.js中间件:

module.exports = () => {
  return async (ctx, next) => {
    ctx.set('Access-Control-Allow-Origin', '*');
    ctx.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
    ctx.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
    if (ctx.method === 'OPTIONS') {
      ctx.status = 204;
    } else {
      await next();
    }
  };
};
// 在分组中绑定
router.group('/api', app.middleware.cors(), controller.api);

来源互联网整合,作者:小编,如若转载,请注明出处:https://www.aiboce.com/ask/264681.html

Like (0)
小编小编
Previous 2025年10月28日 15:58
Next 2025年10月28日 15:59

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注