06 / 06

How would you implement a request-scoped audit log interceptor that captures both the request and response body in NestJS?

Use Scope.REQUEST so a new interceptor instance is created per request — safe for storing request-level state. Inject the REQUEST token to access the request object. Use tap() to log the response body after the handler completes and catchError() to log failures before re-throwing.

Request-scoped audit interceptor
Design decisions for this pattern:
  1. 1

    Scope.REQUEST ensures a fresh instance per request — no state leaks between requests.

  2. 2

    @Inject(REQUEST) gives direct access to the request object including headers, body, and user.

  3. 3

    tap() logs on success without changing the response value.

  4. 4

    catchError() logs the error but re-throws — exception filters still format the error response.

  5. 5

    Register via APP_INTERCEPTOR with useClass so NestJS manages the REQUEST scope correctly.