乐闻世界logo
搜索文章和话题

How to develop custom Koa middleware and common middleware types

2月21日 15:54

Koa middleware is an async function that accepts two parameters: ctx (context object) and next (function to call the next middleware). Developing custom middleware requires following specific patterns and best practices.

Basic middleware structure:

javascript
async function myMiddleware(ctx, next) { // Pre-logic console.log('Request entered'); // Call next middleware await next(); // Post-logic console.log('Request completed'); } // Use middleware app.use(myMiddleware);

Common middleware types:

  1. Logger middleware:
javascript
function loggerMiddleware(ctx, next) { const start = Date.now(); await next(); const ms = Date.now() - start; console.log(`${ctx.method} ${ctx.url} - ${ms}ms`); }
  1. Authentication middleware:
javascript
async function authMiddleware(ctx, next) { const token = ctx.headers.authorization; if (!token) { ctx.throw(401, 'Unauthorized'); } try { const user = await verifyToken(token); ctx.state.user = user; await next(); } catch (error) { ctx.throw(401, 'Invalid token'); } }
  1. Error handling middleware:
javascript
async function errorHandler(ctx, next) { try { await next(); } catch (err) { ctx.status = err.status || 500; ctx.body = { error: err.message, code: err.code }; ctx.app.emit('error', err, ctx); } }
  1. CORS middleware:
javascript
async function corsMiddleware(ctx, next) { ctx.set('Access-Control-Allow-Origin', '*'); ctx.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE'); ctx.set('Access-Control-Allow-Headers', 'Content-Type, Authorization'); if (ctx.method === 'OPTIONS') { ctx.status = 204; return; } await next(); }
  1. Body parser middleware:
javascript
async function bodyParser(ctx, next) { if (ctx.method !== 'POST' && ctx.method !== 'PUT') { return await next(); } const chunks = []; for await (const chunk of ctx.req) { chunks.push(chunk); } const body = Buffer.concat(chunks).toString(); ctx.request.body = JSON.parse(body); await next(); }

Middleware development best practices:

  1. Naming conventions: Use descriptive function names like authMiddleware, loggerMiddleware
  2. Error handling: Use try-catch to catch errors, avoid affecting other middleware
  3. Performance optimization: Avoid time-consuming operations in middleware
  4. Configuration: Support configuration parameters for flexibility
  5. Documentation: Provide clear usage documentation and examples

Configurable middleware example:

javascript
function createLogger(options = {}) { const { format = 'default', includeQuery = false } = options; return async function logger(ctx, next) { const start = Date.now(); await next(); const ms = Date.now() - start; let log = `${ctx.method} ${ctx.url} - ${ms}ms`; if (includeQuery && Object.keys(ctx.query).length) { log += ` ${JSON.stringify(ctx.query)}`; } console.log(log); }; } // Use configurable middleware app.use(createLogger({ includeQuery: true }));

Middleware composition:

javascript
const compose = require('koa-compose'); const middleware = compose([ loggerMiddleware, authMiddleware, errorHandler ]); app.use(middleware);

The key to developing high-quality middleware is understanding the onion model's execution flow, properly using pre and post logic, and ensuring middleware independence and reusability.

标签:Koa