← 中文资源

简体中文版本

Koa 中间件管道执行顺序

用 koa-compose 把多个中间件组合成显式顺序的管道,演示洋葱模型的穿层执行、提前终止与下游控制。

阅读英文原文

示例说明

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);