Class Middleware

Implementing NestMiddleware

Class middleware can use dependency injection.

src/common/middleware/request-id.middleware.ts

import { Injectable, NestMiddleware } from '@nestjs/common';
import { randomUUID } from 'node:crypto';
import type { NextFunction, Request, Response } from 'express';

@Injectable()
export class RequestIdMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    const id = (req.headers['x-request-id'] as string) ?? randomUUID();
    req.headers['x-request-id'] = id;
    res.setHeader('X-Request-Id', id);     // client can quote it in a support ticket
    next();
  }
}

A Request Logger

src/common/middleware/logger.middleware.ts

import { Injectable, Logger, NestMiddleware } from '@nestjs/common';
import type { NextFunction, Request, Response } from 'express';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  private readonly logger = new Logger('HTTP');

  use(req: Request, res: Response, next: NextFunction) {
    const start = process.hrtime.bigint();
    res.on('finish', () => {
      const ms = Number(process.hrtime.bigint() - start) / 1e6;
      this.logger.log(`${req.method} ${req.originalUrl} ${res.statusCode} ${ms.toFixed(1)}ms - ${req.headers['x-request-id']}`);
    });
    next();
  }
}

Example

curl -s http://localhost:3000/products > /dev/null
curl -s http://localhost:3000/products/999 > /dev/null

Example output

[Nest] 23110  - LOG [HTTP] GET /products 200 4.2ms - 9b2f0f8e-6d2c-4f7a-a1d3-3c0f6f1b9e11
[Nest] 23110  - LOG [HTTP] GET /products/999 404 1.8ms - 5d1e7c22-0a47-4b6e-8a2b-77e1c5d3a9f0