typescript / intermediate
Snippet
Designing a Minimal Middleware Pipeline for Task Handlers
Middleware pipelines process requests or background tasks sequentially. By parameterizing middleware functions with generic context boundaries, you achieve extensible request processing while retaining full auto-completion and static verification across steps.
snippet.ts
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
type MiddlewareContext = Record<string, unknown>;type NextFunction = () => Promise<void>;type Middleware<C extends MiddlewareContext> = (ctx: C, next: NextFunction) => Promise<void>;class MiddlewarePipeline<C extends MiddlewareContext> {private middlewares: Middleware<C>[] = [];use(middleware: Middleware<C>): void {this.middlewares.push(middleware);}async execute(context: C): Promise<void> {const run = async (index: number): Promise<void> => {if (index < this.middlewares.length) {const middleware = this.middlewares[index];await middleware(context, () => run(index + 1));}};await run(0);}}interface RequestContext extends MiddlewareContext {userId?: string;isAuthorized: boolean;}const pipeline = new MiddlewarePipeline<RequestContext>();pipeline.use(async (ctx, next) => {ctx.userId = "user_42";await next();});pipeline.use(async (ctx, next) => {ctx.isAuthorized = ctx.userId !== undefined;await next();});await pipeline.execute({ isAuthorized: false });
Breakdown
1
type NextFunction = () => Promise<void>;
Defines the control delegation handle passed into each pipeline middleware layer.
2
type Middleware<C extends MiddlewareContext> = (ctx: C, next: NextFunction) => Promise<void>;
Expresses an asynchronous middleware handler consuming a shared mutable or immutable context object.
3
async execute(context: C): Promise<void>
Recursively invokes pipeline stages in insertion order, allowing onionskin-style pre/post execution.