示例说明
Koa 的中间件是洋葱模型:每个中间件在 await next() 前后分别拥有请求与响应阶段的执行机会。koa-compose 把中间件数组折叠成一个可独立调用的函数,执行顺序即数组顺序。guard 中不调用 next 即提前终止,后续中间件完全不执行,适合做鉴权或熔断短路。
技术要点
- 数组顺序即请求阶段执行顺序
- 不调用 next 实现短路终止
- compose 结果可脱离服务器单独测试
代码解读
timing 在调用下游前记录起点,下游完成后写入耗时响应头,体现同一段代码跨越两个阶段。guard 命中内部路径时直接置 403 并 return,body 中间件不再执行。最后演示 compose 的产物可以传入手工创建的上下文直接跑,便于单元测试断言中间件行为。
使用建议
全局逻辑放靠前的位置,业务逻辑靠后。中间件里捕获下游异常时要区分 4xx 与 5xx 分别记录。compose 的数组应显式声明而不是动态拼接,保证可读性。
代码示例
import Koa from 'koa';
import compose from 'koa-compose';
async function timing(ctx, next) {
const started = Date.now();
await next();
ctx.set('x-response-time', String(Date.now() - started));
}
async function guard(ctx, next) {
if (ctx.path === '/internal') {
ctx.status = 403;
return; // early termination: downstream never runs
}
await next();
}
async function body(ctx) {
ctx.body = { ok: true };
}
const app = new Koa();
app.use(compose([timing, guard, body]));
const pipeline = compose([timing, guard, body]);
const ctx = app.createContext(null, null);
await pipeline(ctx, () => Promise.resolve());
console.log('composed response headers:', ctx.response.status);