📖 Scenario: You are building a simple NestJS application. You want to add a logging interceptor that logs when a request starts and when it ends.
🎯 Goal: Create a logging interceptor in NestJS that logs messages before and after a request is handled.
📋 What You'll Learn
Create a logging interceptor class named LoggingInterceptor
Use the CallHandler and ExecutionContext from NestJS
Log a message before the request is handled
Log a message after the request is handled
Print the final log messages to the console
💡 Why This Matters
🌍 Real World
Logging interceptors help track requests in web applications, useful for debugging and monitoring.
💼 Career
Understanding interceptors and logging is important for backend developers working with NestJS or similar frameworks.
Progress0 / 4 steps
1
Create the LoggingInterceptor class skeleton
Create a class called LoggingInterceptor that implements NestInterceptor. Import NestInterceptor, ExecutionContext, and CallHandler from @nestjs/common. Define the intercept method with parameters context: ExecutionContext and next: CallHandler.
NestJS
Hint
Start by importing the required interfaces and create the class with the intercept method signature.
2
Add pre-request logging
Inside the intercept method, add a console.log statement that prints 'Request started' before calling next.handle().
NestJS
Hint
Use console.log before returning next.handle().
3
Add post-request logging using RxJS tap
Import tap from rxjs/operators. Modify the intercept method to return next.handle().pipe(tap(() => console.log('Request ended'))) so that 'Request ended' is logged after the request completes.
NestJS
Hint
Use pipe and tap to add a post-request log.
4
Print logs by creating an instance and calling intercept
Create an instance of LoggingInterceptor named interceptor. Call interceptor.intercept with dummy arguments: an empty object for context and an object with a handle method that returns of('response') from rxjs. Import of from rxjs. Print the logs by subscribing to the returned observable.
NestJS
Hint
Create a dummy context and next with a handle method returning of('response'). Subscribe to the observable to see logs.
Practice
(1/5)
1. What is the main purpose of a LoggingInterceptor in a NestJS application?
easy
A. To manage user authentication and authorization
B. To handle database connections automatically
C. To log details about incoming requests and outgoing responses
D. To serve static files like images and CSS
Solution
Step 1: Understand the role of interceptors
Interceptors in NestJS run code before and after request handlers, often used for logging or modifying requests/responses.
Step 2: Identify the purpose of LoggingInterceptor
A LoggingInterceptor specifically tracks and logs request and response details for debugging and monitoring.
Final Answer:
To log details about incoming requests and outgoing responses -> Option C
Quick Check:
LoggingInterceptor = logs requests/responses [OK]
Hint: LoggingInterceptor logs request and response info [OK]
Common Mistakes:
Confusing interceptors with middleware
Thinking interceptors handle authentication
Assuming interceptors serve static files
2. Which of the following is the correct way to implement the intercept method in a NestJS LoggingInterceptor?
easy
A. intercept(context, next) { return next.handle(); }
B. intercept(context, next) { next.handle(); }
C. intercept(context) { return next.handle(); }
D. intercept(next) { return context.handle(); }
Solution
Step 1: Recall the intercept method signature
The intercept method receives two parameters: context and next. It must return next.handle() to continue the request lifecycle.
Step 2: Check each option for correct syntax
intercept(context, next) { return next.handle(); } correctly uses both parameters and returns next.handle(). Options A, C, and D either miss parameters or do not return the observable.
Final Answer:
intercept(context, next) { return next.handle(); } -> Option A
Hint: intercept always returns next.handle() with both parameters [OK]
Common Mistakes:
Omitting return statement
Missing one of the parameters
Calling handle on wrong object
3. Given this LoggingInterceptor code snippet, what will be logged when a request is handled?
intercept(context, next) {
const now = Date.now();
return next.handle().pipe(
tap(() => console.log(`Request took ${Date.now() - now}ms`))
);
}
medium
A. Logs the time taken to process the request in milliseconds
B. Logs the request URL only
C. Logs the response body content
D. Logs an error message if the request fails
Solution
Step 1: Analyze the timing logic
The code records the current time before the request is handled, then logs the difference after the response is sent.
Step 2: Understand the logged message
The console.log outputs "Request took Xms" where X is the elapsed time in milliseconds.
Final Answer:
Logs the time taken to process the request in milliseconds -> Option A
Quick Check:
LoggingInterceptor measures request duration [OK]
Hint: Look for Date.now() difference to find elapsed time [OK]
Common Mistakes:
Assuming it logs request URL or body
Thinking it logs errors only
Ignoring the timing calculation
4. Identify the error in this LoggingInterceptor code:
intercept(context, next) {
const now = Date.now();
next.handle().pipe(
tap(() => console.log(`Request took ${Date.now() - now}ms`))
);
}
medium
A. tap operator is not imported
B. Incorrect use of Date.now()
C. Missing context parameter
D. Missing return statement before next.handle()
Solution
Step 1: Check the intercept method return
The intercept method must return the observable from next.handle() to continue the request lifecycle.
Step 2: Identify missing return
The code calls next.handle().pipe(...) but does not return it, so the request will not proceed properly.
Final Answer:
Missing return statement before next.handle() -> Option D
Quick Check:
intercept must return next.handle() observable [OK]
Hint: Always return next.handle() in intercept method [OK]
Common Mistakes:
Forgetting to return the observable
Misusing Date.now() for timing
Ignoring required parameters
5. You want to create a LoggingInterceptor that logs the request method, URL, and the time taken for each request. Which code snippet correctly implements this behavior?