Problem: Factory for Dynamically Composed Middleware Chains
Problem statement
You’re designing a middleware engine where different middleware behaviors (e.g., logging, auth, rate limiting) can be turned on or off using a config array like:
const config = ['logger', 'auth'];
Each middleware is a class with a .handle(req, next) method that must call next() to pass control. You need to generate a composed function that runs the middlewares in order, applying .handle() on each. Each one must wrap the next like a chain of responsibility—a pattern where each handler passes control to the next in a linked sequence.
We’ll cover Chain of Responsibility Pattern separately, but for now, think of it as a way to build modular pipelines where each step decides whether to continue.
Goal
Implement createMiddlewarePipeline(config) that returns a composed middleware function like:
const fn = createMiddlewarePipeline(['logger', 'auth']);await fn(req);
Constraints
No hardcoded branching logic.
The middleware classes are predefined and should not be edited.
The order of execution must match the order in the config array.
The factory must return a single function that handles the full chain.
Sample output
The examples below illustrate what the output should look like:
// Example usageasync function runPipelines() {// Pipeline 1 – Single middlewareconst pipeline1 = createMiddlewarePipeline(['logger']);await pipeline1({});console.log('--- End of pipeline 1 ---');// Pipeline 2 – Two middlewaresconst pipeline2 = createMiddlewarePipeline(['auth', 'logger']);await pipeline2({});console.log('--- End of pipeline 2 ---');// Pipeline 3 – All middlewares in one orderconst pipeline3 = createMiddlewarePipeline(['rateLimit', 'logger', 'auth']);await pipeline3({});console.log('--- End of pipeline 3 ---');// Pipeline 4 – All middlewares in another orderconst pipeline4 = createMiddlewarePipeline(['auth', 'rateLimit', 'logger']);await pipeline4({});console.log('--- End of pipeline 4 ---');// Pipeline 5 – No middlewareconst pipeline5 = createMiddlewarePipeline([]);await pipeline5({});console.log('--- End of pipeline 5 ---');}runPipelines();/* Expected output:Logger startLogger end--- End of pipeline 1 ---Auth startLogger startLogger endAuth end--- End of pipeline 2 ---RateLimit startLogger startAuth startAuth endLogger endRateLimit end--- End of pipeline 3 ---Auth startRateLimit startLogger startLogger endRateLimit endAuth end--- End of pipeline 4 ------ End of pipeline 5 --- */
Good luck trying the problem! If you’re unsure how to proceed, check the “Solution” tab above.
Problem: Factory for Dynamically Composed Middleware Chains
Problem statement
You’re designing a middleware engine where different middleware behaviors (e.g., logging, auth, rate limiting) can be turned on or off using a config array like:
const config = ['logger', 'auth'];
Each middleware is a class with a .handle(req, next) method that must call next() to pass control. You need to generate a composed function that runs the middlewares in order, applying .handle() on each. Each one must wrap the next like a chain of responsibility—a pattern where each handler passes control to the next in a linked sequence.
We’ll cover Chain of Responsibility Pattern separately, but for now, think of it as a way to build modular pipelines where each step decides whether to continue.
Goal
Implement createMiddlewarePipeline(config) that returns a composed middleware function like:
const fn = createMiddlewarePipeline(['logger', 'auth']);await fn(req);
Constraints
No hardcoded branching logic.
The middleware classes are predefined and should not be edited.
The order of execution must match the order in the config array.
The factory must return a single function that handles the full chain.
Sample output
The examples below illustrate what the output should look like:
// Example usageasync function runPipelines() {// Pipeline 1 – Single middlewareconst pipeline1 = createMiddlewarePipeline(['logger']);await pipeline1({});console.log('--- End of pipeline 1 ---');// Pipeline 2 – Two middlewaresconst pipeline2 = createMiddlewarePipeline(['auth', 'logger']);await pipeline2({});console.log('--- End of pipeline 2 ---');// Pipeline 3 – All middlewares in one orderconst pipeline3 = createMiddlewarePipeline(['rateLimit', 'logger', 'auth']);await pipeline3({});console.log('--- End of pipeline 3 ---');// Pipeline 4 – All middlewares in another orderconst pipeline4 = createMiddlewarePipeline(['auth', 'rateLimit', 'logger']);await pipeline4({});console.log('--- End of pipeline 4 ---');// Pipeline 5 – No middlewareconst pipeline5 = createMiddlewarePipeline([]);await pipeline5({});console.log('--- End of pipeline 5 ---');}runPipelines();/* Expected output:Logger startLogger end--- End of pipeline 1 ---Auth startLogger startLogger endAuth end--- End of pipeline 2 ---RateLimit startLogger startAuth startAuth endLogger endRateLimit end--- End of pipeline 3 ---Auth startRateLimit startLogger startLogger endRateLimit endAuth end--- End of pipeline 4 ------ End of pipeline 5 --- */
Good luck trying the problem! If you’re unsure how to proceed, check the “Solution” tab above.