问题难点
在实现复杂的业务逻辑时,如何正确使用中间件处理请求、如何设计高效的控制器成为关键问题。
解决方案
Egg.js提供了灵活的中间件机制和基于装饰器的控制器实现方式。
Demo代码:
// app/middleware/auth.ts - 认证中间件import{Context,Next}from'egg';exportdefaultfunctionauth(options:{required?:boolean}={}){returnasync(ctx:Context,next:Next)=>{consttoken=ctx.request.header.authorization;if(options.required!==false&&!token){ctx.status=401;ctx.body={error:'未提供认证令牌'};return;}// 简单的token验证逻辑try{// 实际应用中应使用JWT或其他安全的认证方式if(token==='Bearer valid-token'){ctx.user={id:1,name:'admin'};// 将用户信息挂载到上下文awaitnext();}else{ctx.status=401;ctx.body={error:'无效的认证令牌'};}}catch(error){ctx.status=500;ctx.body={error:'认证服务异常'};}};}// config/config.default.ts - 配置中间件import{EggAppConfig,PowerPartial}from'egg';exportdefault()=>{constconfig:PowerPartial<EggAppConfig>={};config.middleware=['auth','robot'];// 应用全局中间件// 中间件配置config.auth={required:true,};config.robot={ua:[/Baiduspider/i],};returnconfig;};// app/controller/user.ts - 控制器实现import{Controller}from'egg';exportdefaultclassUserControllerextendsController{/** * 获取用户列表 */publicasyncindex(){const{ctx}=this;constquery={page:parseInt(ctx.query.page)||1,pageSize:parseInt(ctx.query.pageSize)||10,};try{constresult=awaitctx.service.user.list(query);ctx.body={success:true,data:result.users,pagination:result.pagination,};}catch(error){ctx.logger.error('获取用户列表失败:',error);ctx.body={success:false,message:'获取用户列表失败',};ctx.status=500;}}/** * 创建新用户 */publicasynccreate(){const{ctx}=this;try{constuserData=ctx.request.body;constuser=awaitctx.service.user.create(userData);ctx.body={success:true,data:user,};ctx.status=201;}catch(error){ctx.logger.error('创建用户失败:',error);ctx.body={success:false,message:error.message||'创建用户失败',};ctx.status=400;}}/** * 获取指定用户 */publicasyncshow(){const{ctx}=this;constid=ctx.params.id;try{constuser=awaitctx.service.user.findById(id);if(!user){ctx.status=404;ctx.body={success:false,message:'用户不存在',};return;}ctx.body={success:true,data:user,};}catch(error){ctx.logger.error(`获取用户${id}失败:`,error);ctx.body={success:false,message:'获取用户失败',};ctx.status=500;}}}