Koa's Onion Model is its most core design feature, implementing middleware execution flow control through async/await. In the onion model, middleware executes in registration order, forming a layered structure similar to an onion.
Execution flow:
- Request enters from outer middleware, passing inward layer by layer
- Each middleware executes "pre-logic" before await next()
- Execute await next() to enter the next layer of middleware
- After reaching the innermost layer, start returning outward layer by layer
- Each middleware executes "post-logic" after await next()
- Final response returns to client from outermost middleware
Code example:
javascriptconst Koa = require('koa'); const app = new Koa(); app.use(async (ctx, next) => { console.log('1 - pre'); await next(); console.log('1 - post'); }); app.use(async (ctx, next) => { console.log('2 - pre'); await next(); console.log('2 - post'); }); app.use(async (ctx) => { console.log('3 - core'); ctx.body = 'Hello Koa'; }); // Execution order: 1-pre -> 2-pre -> 3-core -> 2-post -> 1-post
Advantages of onion model:
- Clear execution order: Pre and post logic separated, clear code structure
- Flexible control: Each middleware can decide whether to continue downstream
- Unified error handling: Can catch all middleware errors through try-catch
- Middleware reuse: Can reuse middleware logic at different positions
- Request/response handling: Convenient to execute different logic when request enters and response returns
Practical application scenarios:
- Logging: Record request and response info in pre/post logic
- Error handling: Unified capture and handle errors in outer middleware
- Authentication: Verify user identity in pre-logic
- Response time statistics: Calculate total request processing time
- Response formatting: Unified response format handling in post-logic