第2篇:路由系统与控制器开发实践

一、Router配置规则与RESTful风格设计

在这里插入图片描述

1. 路由基础配置

Egg.js采用Koa风格的链式路由配置语法,支持多种请求方法:

// app/router.js
module.exports = app => {
  const { router, controller } = app;
  
  // 基础路由配置
  router.get('/news', controller.news.list);
  router.post('/news', controller.news.create);
  router.del('/news/:id', controller.news.delete);
  
  // 同时注册多个方法
  router.resources('posts', '/api/posts', controller.posts);
};

2. RESTful最佳实践

资源操作请求方法路由示例控制器方法
获取列表GET/usersindex
获取单个GET/users/:idshow
创建资源POST/userscreate
更新全部PUT/users/:idupdate
局部更新PATCH/users/:idpatch
删除资源DELETE/users/:iddestroy

推荐使用app.resources快速生成标准路由:

router.resources('users', '/api/v1/users', controller.v1.users);

3. 特殊路由配置

// 重定向路由
router.redirect('/old', '/new', 302);

// 通配符路由
router.get(/^\/api\/(.*)/, controller.api.proxy);

// 参数约束
router.get('/user/:id(\\d+)', controller.user.detail);

// 路由别名
router.get('userHome', '/user/:name', controller.user.home);

二、控制器(Controller)职责与最佳实践

1. 控制器核心职责

  • 输入校验:验证请求参数的合法性
  • 流程控制:协调Service层和View层的交互
  • 响应处理:返回标准化响应格式

2. 最佳实践示例

// app/controller/user.js
const Controller = require('egg').Controller;

class UserController extends Controller {
  async create() {
    const { ctx } = this;
    
    // 1. 参数校验
    ctx.validate({
      username: { type: 'string', required: true },
      password: { type: 'password', min: 6 }
    });

    // 2. 调用Service
    const user = await ctx.service.user.create(ctx.request.body);

    // 3. 统一响应格式
    ctx.success({
      code: 201,
      data: user,
      message: '用户创建成功'
    });
  }
}

3. 控制器开发规范

  • 保持简洁:单个方法不超过50行代码
  • 禁止包含:业务逻辑应放在Service层
  • 异常处理:统一错误处理中间件捕获异常
  • 命名约定
    • 方法名使用RESTful标准动词(index/show/create/update/destroy)
    • 文件名为复数形式(users.js)

三、参数传递与响应处理规范

1. 参数获取方式

参数类型获取方式示例
路径参数ctx.params/users/:id → id
查询参数ctx.query?name=egg → name
请求体ctx.request.bodyPOST/PUT请求体
头部信息ctx.headersAuthorization头
Cookiectx.cookies.get()用户凭证

2. 参数校验示例

安装校验插件:

npm install egg-validate --save

控制器中使用:

// 简单校验
ctx.validate({
  page: { type: 'int', required: false, default: 1 },
  pageSize: { type: 'int', max: 100 }
});

// 自定义校验规则
ctx.validate({
  mobile: {
    type: 'string',
    format: /^1[3-9]\d{9}$/,
    message: '手机号格式错误'
  }
}, ctx.request.body);

3. 响应处理规范

推荐使用统一响应格式中间件:

// app/middleware/response_formatter.js
module.exports = () => {
  return async (ctx, next) => {
    try {
      await next();
      
      if (ctx.body && !ctx.body.code) {
        ctx.body = {
          code: 200,
          data: ctx.body,
          message: 'success'
        }
      }
    } catch (err) {
      ctx.status = err.status || 500;
      ctx.body = {
        code: ctx.status,
        message: err.message,
        data: null
      };
    }
  };
};

四、路由分组与模块化方案

1. 路由分组实践

// 版本分组
router.namespace('/api/v1', v1 => {
  v1.resources('users', '/users', controller.v1.users);
  v1.resources('posts', '/posts', controller.v1.posts);
});

router.namespace('/api/v2', v2 => {
  v2.resources('users', '/users', controller.v2.users);
});

// 权限分组
const admin = router.namespace('/admin');
admin.get('/dashboard', middleware.authAdmin(), controller.admin.dashboard);
admin.resources('articles', '/articles', controller.admin.articles);

2. 模块化路由方案

创建app/router目录:

app/router/
├── api.js
├── admin.js
└── web.js

主路由文件加载子路由:

// app/router.js
module.exports = app => {
  require('./router/api')(app);
  require('./router/admin')(app);
  require('./router/web')(app);
};

3. 动态加载路由

// app/router/modules.js
const fs = require('fs');
const path = require('path');

module.exports = app => {
  const dir = path.join(app.baseDir, 'app/router/modules');
  fs.readdirSync(dir)
    .filter(f => f.endsWith('.js'))
    .forEach(f => require(path.join(dir, f))(app));
};

五、总结与最佳实践清单

  1. 路由设计原则

    • 遵循RESTful规范
    • 使用动词表示资源操作
    • 版本控制通过URL路径实现
  2. 控制器开发规范

    • 保持单一职责原则
    • 参数校验前置处理
    • 业务逻辑委托给Service层
  3. 参数处理建议

    • 敏感参数使用POST请求
    • 分页参数统一命名(page/pageSize)
    • 响应数据使用DTO转换
  4. 大型项目路由管理

    • 按业务模块拆分路由文件
    • 使用中间件处理通用逻辑
    • 定期清理废弃路由

下篇预告:《请求参数处理与数据校验》将深入探讨:

  • 多场景参数获取(Query/Params/Body)
  • 使用egg-validate进行数据校验
  • 文件上传与Stream处理技巧
  • 自定义校验规则与错误处理

欢迎在评论区留下你的路由设计经验或遇到的挑战,共同探讨最佳实践!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值