Software Engineer | 41 questions | 2026
NestJS Interview Questions and Answers
NestJS interview questions for freshers 14
Q1FresherMost askedAnswerHideWhat is NestJS and why would you choose it over plain Express?
NestJS is a TypeScript-first Node.js framework for server-side apps. It adds structure (modules, controllers, providers) and dependency injection on top of Express or Fastify.
Why choose it:
- Enforced architecture, so large teams write code the same way.
- Built-in DI makes services easy to test and swap.
- First-class support for validation, config, OpenAPI, GraphQL, WebSockets and microservices.
- Decorators for routing, guards and pipes keep controllers thin.
Downsides: more repeated setup code and a learning curve compared with a 50-line Express app. For tiny scripts, plain Express or Fastify is fine.
What they are checking: Whether you can explain a framework choice with its pros and cons
Q2FresherMost askedAnswerHideWhat is a module in NestJS and what does it contain?
A module is a class decorated with @Module() that groups related controllers and providers together. Every app has at least a root module.
@Module({
imports: [DatabaseModule], // other modules whose exports we need
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService], // what other modules may inject
})
export class UsersModule {}
- Providers are private to a module unless listed in
exports. - A module must import another module to use its exported providers.
- Modules are singletons by default, so a shared module is instantiated once.
What they are checking: Whether you understand encapsulation between modules
Q3FresherMost askedAnswerHideWhat is the role of a controller in NestJS?
A controller handles incoming requests, extracts input, calls a service, and returns the response; it should contain no business logic.
@Controller('users')
export class UsersController {
constructor(private readonly users: UsersService) {}
@Get(':id')
findOne(@Param('id', ParseIntPipe) id: number) {
return this.users.findOne(id);
}
@Post()
@HttpCode(201)
create(@Body() dto: CreateUserDto) {
return this.users.create(dto);
}
}
Decorators such as @Get, @Post, @Param, @Query, @Body and @Headers map HTTP to method arguments. Return a value or a promise, and Nest serialises it.
What they are checking: Whether you keep controllers thin and know the routing decorators
Q4FresherMost askedAnswerHideWhat are providers in NestJS and what does @Injectable do?
A provider is any class (service, repository, factory, helper) that Nest can inject as a dependency. @Injectable() marks the class so Nest's DI container can manage it and read its constructor metadata.
@Injectable()
export class UsersService {
constructor(private readonly repo: UsersRepository) {}
findOne(id: number) { return this.repo.findById(id); }
}
Register it in the providers array of a module. By default it is a singleton shared across the module graph. Business logic belongs in providers, which makes it reusable and easy to unit test with a mock.
What they are checking: Whether you understand providers as the home of business logic
Q5FresherMost askedAnswerHideHow does dependency injection work in NestJS?
Nest has an IoC container. It reads the types of constructor parameters (from TypeScript metadata). It finds the provider registered under that token, creates it once, and injects it.
@Injectable()
export class OrdersService {
constructor(
private readonly users: UsersService, // class token
@Inject('PAYMENT_CLIENT') private readonly pay: PaymentClient, // string token
) {}
}
Steps: build a dependency graph from modules, resolve providers in order, instantiate singletons, then inject. Interfaces vanish at runtime, so inject them with a string, symbol or class token using @Inject(). Benefits: loose coupling and simple mocking in tests.
What they are checking: Whether you know tokens and how Nest resolves the graph
Q6FresherMost askedAnswerHideWhat is the difference between middleware, guards, interceptors, pipes and exception filters?
Each handles a different concern at a different point of the request lifecycle.
| Building block | Runs | Typical job |
|---|---|---|
| Middleware | First, before routing context | Logging, CORS, body parsing, request id |
| Guard | Before the handler | Authentication, authorisation (returns true or false) |
| Interceptor | Around the handler | Transform response, cache, timing, map errors |
| Pipe | Before the handler, per argument | Validate and transform input |
| Exception filter | On thrown errors | Shape error responses, log |
Key difference: middleware does not know which handler will run. Guards, interceptors and pipes have an ExecutionContext and know which controller and method will run. Pick the narrowest tool: validation in pipes, permissions in guards, and shared before-and-after logic in interceptors.
What they are checking: Whether you pick the right layer for each concern
Q7FresherMost askedFree with sign-inAnswerHideHow do you validate request bodies with DTOs and class-validator?
Define a DTO class with class-validator decorators and enable the global ValidationPipe. It checks incoming data. If the check fails, it returns a 400 with messages.
Q8FresherMost askedFree with sign-inAnswerHideHow do you integrate a database in NestJS using TypeORM?
Install @nestjs/typeorm and typeorm, configure TypeOrmModule.forRootAsync with your config. Define entities. Then register repositories in each feature module with forFeature.
Q9FresherMost askedFree with sign-inAnswerHideHow do you manage configuration and environment variables in NestJS?
Use @nestjs/config: ConfigModule.forRoot loads .env files and gives values through ConfigService. Add validation, so the app stops at once if a setting is missing.
Q10FresherMost askedFree with sign-inAnswerHideHow do you unit test a NestJS service?
Build a testing module with Test.createTestingModule. Provide the service under test plus mocks for its dependencies. Then check its behaviour.
Q11FresherMost askedFree with sign-inAnswerHideWhat is the difference between pipes and exception filters?
Pipes work on input before the handler (they check or change arguments). Exception filters work on errors after something throws, and turn them into responses.
Q12FresherMost askedFree with sign-inAnswerHideWhat are interceptors used for in NestJS? Give an example.
Interceptors wrap the handler using RxJS. So they can run logic before and after it, change the result, add caching, measure time, or change errors.
Q13FresherMost askedFree with sign-inAnswerHideWhat does the @Global decorator do and when should you avoid it?
@Global() makes a module's exported providers available everywhere without importing the module in each consumer.
Q14FresherMost askedFree with sign-inAnswerHideHow do you document a NestJS API with Swagger (OpenAPI)?
Install @nestjs/swagger, build a document in main.ts with DocumentBuilder, and expose it with SwaggerModule.setup. Decorators or the CLI plugin describe the DTOs and endpoints.
NestJS interview questions for experienced 17
Q15ExperiencedMost askedAnswerHideWhat are custom providers (useClass, useValue, useFactory, useExisting) and when do you use each?
Custom providers let you control how a token is resolved.
| Form | Use for |
|---|---|
useClass | Swap an implementation per environment |
useValue | Constants, config objects, mocks in tests |
useFactory | Build dynamically, with inject of other providers, optionally async |
useExisting | Create an alias to another provider |
@Module({
providers: [
{ provide: 'CACHE', useFactory: async (cfg: ConfigService) => {
const client = createClient({ url: cfg.get('REDIS_URL') });
await client.connect();
return client;
},
inject: [ConfigService] },
{ provide: PaymentGateway, useClass: process.env.NODE_ENV === 'test' ? FakeGateway : StripeGateway },
],
})
export class AppModule {}
Async factories delay app start until they resolve, which is useful for connections.
What they are checking: Whether you can wire non-trivial dependencies cleanly
Q16ExperiencedMost askedAnswerHideWhat is a circular dependency in NestJS and how do you resolve it with forwardRef?
A circular dependency happens when two providers (or modules) need each other. Nest cannot decide which to create first. forwardRef() delays the reference, so both can be resolved later.
@Injectable()
export class AService {
constructor(@Inject(forwardRef(() => BService)) private b: BService) {}
}
@Injectable()
export class BService {
constructor(@Inject(forwardRef(() => AService)) private a: AService) {}
}
// modules need it too:
@Module({ imports: [forwardRef(() => BModule)] })
export class AModule {}
This is only a workaround. The better fix is to remove the cycle. Move the shared logic to a third service, use events (EventEmitter2) for one direction, or move the code to the right module. Also watch for circular file imports. They show up as undefined.
What they are checking: Whether you treat forwardRef as a last resort and know design fixes
Q17ExperiencedMost askedAnswerHideWhat is the order of the NestJS request lifecycle?
Incoming request flow is: middleware, guards, interceptors (before), pipes, controller handler, service, interceptors (after), exception filters (only on errors), then the response.
- Global, then module-bound middleware.
- Guards (global, controller, route).
- Interceptors, pre-controller part.
- Pipes (global, controller, route, param).
- Controller method and service.
- Interceptors, post-response part (reverse order).
- Exception filters catch anything thrown from the guard onward.
Within each type, global runs first, then controller-level, then route-level. Interceptors unwind in reverse on the way out. A guard that returns false stops the pipeline before pipes and the handler.
What they are checking: Whether you can place each building block in the pipeline
Q18ExperiencedMost askedAnswerHideHow do guards work in NestJS and how would you implement role-based access control?
A guard implements CanActivate and returns a boolean (or promise or observable) that decides whether the request proceeds. For RBAC, combine a roles decorator that stores metadata with a guard that reads it using Reflector.
export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(ctx: ExecutionContext): boolean {
const required = this.reflector.getAllAndOverride<string[]>('roles', [ctx.getHandler(), ctx.getClass()]);
if (!required) return true;
const { user } = ctx.switchToHttp().getRequest();
return required.some(r => user?.roles?.includes(r));
}
}
@Roles('admin')
@UseGuards(JwtAuthGuard, RolesGuard)
@Delete(':id')
remove(@Param('id') id: string) {}
Order matters: authentication first so request.user exists. Returning false gives 403.
What they are checking: Whether you can implement authorisation with metadata and guards
Q19ExperiencedMost askedFree with sign-inAnswerHideHow do you run a database transaction in NestJS?
Run all related writes in one transaction so they either all commit or all roll back. With TypeORM use a DataSource and a query runner or the transaction helper; with Prisma use $transaction.
Q20ExperiencedMost askedFree with sign-inAnswerHideHow do you implement JWT authentication with Passport in NestJS?
Use @nestjs/passport with passport-jwt. A login endpoint checks the credentials and issues a signed token with JwtService. A JwtStrategy plus AuthGuard('jwt') protects routes.
Q21ExperiencedMost askedFree with sign-inAnswerHideWhat are provider scopes in NestJS (DEFAULT, REQUEST, TRANSIENT)?
Scope sets how long a provider lives. DEFAULT is one instance for the whole app (a singleton). REQUEST makes a new instance for each incoming request. TRANSIENT makes a new instance for each class that injects it.
Q22ExperiencedMost askedFree with sign-inAnswerHidePrisma versus TypeORM in a NestJS project: how do you choose?
Pick Prisma for type-safe queries, a clear schema file and good migrations. Pick TypeORM when you prefer decorators, the Active Record or Data Mapper style, or need features such as complex entity inheritance.
Q23ExperiencedMost askedFree with sign-inAnswerHideHow would you design refresh tokens and logout with JWT in NestJS?
Issue a short-lived access token (about 15 minutes) and a long-lived refresh token. Store the refresh token on the server as a hash, and replace it on each use.
Q24ExperiencedMost askedFree with sign-inAnswerHideWhat are the transport options for NestJS microservices, and how do you set one up?
Nest abstracts transports so the same patterns work over TCP, Redis, NATS, MQTT, RabbitMQ, Kafka and gRPC. You create a microservice app with NestFactory.createMicroservice and call it from a client built with ClientProxy.
Q25ExperiencedMost askedFree with sign-inAnswerHideWhat does the transform option of ValidationPipe do, and what is class-transformer used for?
With transform: true the pipe turns the plain payload into an instance of the DTO class, and changes simple values to the declared type. It uses class-transformer.
Q26ExperiencedMost askedFree with sign-inAnswerHideWhat is the difference between @MessagePattern and @EventPattern?
@MessagePattern handles request-response messages, where the sender waits for a reply. @EventPattern handles fire-and-forget events, with no reply.
Q27ExperiencedMost askedFree with sign-inAnswerHideHow do you write end-to-end tests for a NestJS API?
Create the full app (or a part of it) from AppModule in a testing module. Then call it over HTTP with supertest, without opening a real port.
Q28ExperiencedMost askedFree with sign-inAnswerHideWhat are dynamic modules in NestJS (forRoot, forRootAsync, forFeature)?
A dynamic module is a module whose providers are set up when it is imported. A static method that returns a DynamicModule does this. So one reusable module can be set up in a different way by each user.
Q29ExperiencedMost askedFree with sign-inAnswerHideWhat are the differences between using Express and Fastify as the HTTP adapter in NestJS?
Nest works with different platforms. Express is the default and has the most middleware. Fastify handles more requests per second and uses fewer resources, with a design built around schemas.
Q30ExperiencedMost askedFree with sign-inAnswerHideHow do you create a custom parameter decorator, for example @CurrentUser()?
Use createParamDecorator to pull a value out of the ExecutionContext so controllers stay clean.
Q31ExperiencedMost askedFree with sign-inAnswerHideWhich design patterns do you commonly use in NestJS applications, and where do they appear?
NestJS is built around several patterns, and I also apply others on top of it.
Scenario based NestJS interview questions 10
Q32ExperiencedMost askedScenarioFree with sign-inAnswerHideHow would you design an idempotent payment endpoint so a retry never charges the customer twice?
Require an Idempotency-Key header made by the client. Store the key with a fingerprint of the request and the result. Then a repeat gets the saved response and does not run again.
Q33ExperiencedMost askedScenarioFree with sign-inAnswerHideDesign a reconciliation job that matches your payment records against a provider's settlement file.
Compare both sources by a stable key, classify the differences, and make the job re-runnable and auditable.
Q34ExperiencedMost askedScenarioFree with sign-inAnswerHideAn endpoint that lists orders is slow under load. How do you diagnose and fix it?
Measure first, then fix the biggest cost, which is usually the database.
Q35ExperiencedMost askedScenarioFree with sign-inAnswerHideTwo requests update the same account balance at the same time and the final balance is wrong. How do you prevent this?
This is a lost-update race. Prevent it by letting the database handle changes one at a time. Use an atomic update, a row lock, or optimistic versioning.
Q36FresherMost askedScenarioFree with sign-inAnswerHideTwo services are circularly dependent in your NestJS codebase and the app fails to boot. How do you refactor it properly?
Find why each one needs the other. Then break the cycle by moving shared logic or reversing one direction, instead of leaving forwardRef everywhere.
Q37ExperiencedMost askedScenarioFree with sign-inAnswerHideHow would you integrate multiple payment gateways behind one interface in NestJS?
Define one common interface and implement it for each gateway (adapter). Then pick the right one at run time (strategy) through DI.
Q38ExperiencedMost askedScenarioFree with sign-inAnswerHideHow would you add rate limiting and brute-force protection to a login endpoint?
Apply a global throttler, with a stricter limit on login routes. Count by IP and by account. Slow attackers down more after repeated failures.
Q39ExperiencedMost askedScenarioFree with sign-inAnswerHideHow do you run background jobs reliably in NestJS, such as sending emails with retries?
Use a queue (BullMQ with Redis through @nestjs/bullmq) so work is persisted, retried and processed outside the request.
Q40ExperiencedMost askedScenarioFree with sign-inAnswerHideHow do you safely handle incoming webhooks, for example from a payment provider?
Verify authenticity, acknowledge fast, and process each event exactly once by its id.
Q41ExperiencedMost askedScenarioFree with sign-inAnswerHideHow do you add health checks and graceful shutdown to a NestJS service running in containers?
Add liveness and readiness endpoints with @nestjs/terminus. Enable shutdown hooks, so work in progress finishes before the process exits.