59 NestJS interview questions with detailed answers, sorted from basic to advanced. Free to practice, with progress saved automatically.
NestJS is a TypeScript framework for building server-side applications on Node.js, structured around modules and dependency injection in a style influenced by Angular. Coverage includes modules and custom providers, the request pipeline from middleware to guards, interceptors, pipes, and exception filters, validation, ORM integration, authentication, microservices and messaging, and testing for production.
and 3 more topics.
NestJS is a Node.js framework written in TypeScript and inspired by Angular. It does not replace Express: it runs on top of Express (the default) or Fastify and adds a ready-made project structure: Modules, Controllers, Providers and Dependency Injection. Plain Express NestJS --------- Folder structure,…
A module is a class decorated with @Module() that groups the controllers and services of one feature. Every app has at least one root module, AppModule. - providers: Nest instantiates them and injects them where needed. By default they are usable only inside this module.…
A controller is a class that receives HTTP requests and returns responses. It handles only the HTTP part: read request data, call a service, return the result. Routes are declared with decorators. Nest combines 'users' and ':id' into the route /users/:id. For GET /users/42, @Param('id')…
A provider is a class that NestJS instantiates and hands to whoever needs it, usually a service or repository marked with @Injectable(). Dependency Injection (DI) means a class does not new its dependencies itself; it declares them in the constructor and Nest passes them in.…
Every request into NestJS passes through a fixed chain of layers. Each layer has one job, so knowing the order tells you where logic belongs. Why the order is what it is: - Middleware runs first because it works at the Express level, sees only…
A guard is a class implementing CanActivate that decides whether a request may reach the handler. Return true to continue; return false and Nest responds 403; for a different status, throw from the guard. A minimal JWT auth guard: read the Bearer token from the…
A pipe is a class implementing PipeTransform that runs right before the handler and processes its arguments: validation (throw on bad data, 400) or transformation (change the type, like ParseIntPipe turning "42" into 42). The built-in ValidationPipe reads class-validator decorators on a DTO and checks…
An interceptor is a class implementing NestInterceptor that wraps the call to the handler. Because it wraps the call, it can run code both before and after the handler and change what the handler returns, which guards and pipes cannot do. The handler only runs…
An exception filter catches exceptions thrown while handling a request (from guards, pipes, handlers) and decides the error response. Nest's default filter: an HttpException (such as NotFoundException) returns its own status and message; anything else returns 500. To give every error one format and log…
Integration via @nestjs/typeorm takes three steps: declare the connection with TypeOrmModule.forRoot in AppModule, register entities in a feature module, and inject a Repository into the service. A repository does all reads and writes for one entity, while the entity is just a class describing a…
JWT auth in NestJS has two halves. Issuing: AuthService checks email + password and signs a JWT with JwtService from @nestjs/jwt. Verifying: Passport's JwtStrategy reads the token from the Authorization: Bearer ... header, checks the signature and expiry, then attaches user info to req.user. A…
@nestjs/config reads environment variables (from process.env and a .env file). ConfigModule loads and checks the config when the app starts; ConfigService is the provider you inject wherever you need a value. At runtime: - JWTSECRET missing: the app stops at startup with "JWTSECRET" is required.…
NestJS tests run on Jest, and the Nest-specific piece is Test.createTestingModule(): it builds a DI container like the real app but lets you swap providers. A unit test builds a module containing only the class under test, with every dependency mocked. An integration test builds…
Prisma is an ORM where you describe tables in a schema.prisma file, then run prisma generate to produce Prisma Client, typed for each model and each query. In NestJS, you wrap that client in a provider and inject it like a service. PrismaService extends PrismaClient,…
NestJS handles uploads (multipart/form-data) with Multer, which ships inside @nestjs/platform-express. Every upload route has two pieces: an interceptor that reads the file from the request (FileInterceptor for one file, FilesInterceptor for several), and a param decorator that hands the file to the handler (@UploadedFile() /…
Custom decorators in NestJS come in two kinds that do different jobs. A param decorator (createParamDecorator) pulls a value from the request into a handler parameter, like @CurrentUser. A metadata decorator (SetMetadata) only attaches a label to a route, like @Roles or @Public; on its…
Swagger (OpenAPI) is a standard description of an API: which endpoints exist, what body they take, what they return. @nestjs/swagger generates it from controllers and DTOs, plus a Swagger UI page where the frontend can browse and try the API. When the app runs, /docs…
NestJS has three provider scopes. They decide when a provider's instance is created and who shares it. - DEFAULT (singleton): one instance for the whole app, created once at startup. This is the default and suits services that hold no per-request data, such as ConfigService…
A dynamic module lets you pass parameters when importing a module, so the same module can be configured differently in each app. A static module, by contrast, has its configuration fixed in code. The module has a static method that returns a DynamicModule, an object…
Custom providers control how NestJS creates and injects dependencies. Each provider declares a provide (the token) and a way to produce the value for that token: useValue: use a ready-made value — typically a config object, or a mock when writing tests: The place that…
ExecutionContext is the object NestJS passes to guards and interceptors so they know which transport the request came from and which handler is about to run. It extends ArgumentsHost, which wraps the handler's raw arguments (for HTTP: req, res, next). Exception filters receive only an…
Transactions ensure all DB operations succeed or roll back entirely. Option 1 — QueryRunner (recommended for complex transactions): Option 2 — EntityManager.transaction(): Note: do not mix DI repositories and queryRunner.manager in the same transaction. Both draw connections from the same pool, but the transaction lives…
Repository API: best for simple CRUD, readable, type-safe: Query Builder: for complex dynamic queries: A common gotcha: a condition on a leftJoined table placed in where/andWhere (such as post.publishedAt :date) drops every user without a matching post, because for those users post.publishedAt is NULL. The…
Helmet: middleware that sets HTTP security headers (CSP, X-Frame-Options against clickjacking, X-Content-Type-Options against MIME sniffing, HSTS...). Helmet only sets headers, so it is an extra layer and does not replace sanitizing input against XSS: CORS: allow specific origins only: Rate limiting with @nestjs/throttler. ThrottlerModule.forRoot only…
JWT (Stateless): token carries all info, server needs no state. Good fit when several services must authenticate requests (each verifies the signature itself without calling a shared store), for mobile apps (token in Keychain/Keystore, sent in the Authorization header), and for APIs used across domains…
To unit test a service in NestJS, build a small TestingModule containing only the service under test, and replace each dependency with a mock. The test then never touches the DB or other services. What happens in the code above: - Test.createTestingModule builds a module…
An E2E test in NestJS boots the whole AppModule inside the test process, then uses Supertest to send real HTTP requests to it and check the responses. Unlike a unit test, the request goes through the whole pipeline: pipes, guards, controller, service, down to the…
NestJS provides @nestjs/event-emitter (a wrapper around EventEmitter2) for internal events: this is pub/sub inside a single process, not distributed messaging between services. Async events: add { async: true } (@OnEvent('order.created', { async: true })) so the handler runs on a later turn and emit does…
Offset-based: simple, supports random page access: Downside: unstable when data changes, slow with large skip. Cursor-based: stable for real-time feeds, scales better: The cursor must include id, not just createdAt: if several rows share a timestamp and a page ends in the middle of that…
class-transformer together with ClassSerializerInterceptor automatically strips or transforms fields in the response. Exclude sensitive fields (password, tokens): Enable it for the whole app: Return the entity from the controller. ParseIntPipe converts id from a string (the value read from the URL) to a number; without…
TypeORM ships convenient decorators for timestamps and soft delete: Soft delete with TypeORM: Keep the parent class abstract and without @Entity(): with it, TypeORM creates a separate table for the parent too. Also avoid the name BaseEntity, because TypeORM already exports a BaseEntity class (Active…
A connection pool is a set of database connections opened in advance and reused. Opening a new Postgres connection costs a TCP handshake, TLS and authentication, so each query just borrows a connection from the pool and returns it. With TypeORM + Postgres the pool…
NestJS has no global provider registry (except modules marked @Global()): each module is its own DI scope. For OrderService (in OrderModule) to inject UserService (in UserModule), both must hold: 1. UserModule exports UserService. 2. OrderModule imports UserModule. Reading the message: the ? marks the constructor…
Middleware runs before the router decides which handler will execute, so it does not know the target route handler and cannot read metadata attached to it. Middleware only gets plain Express-style req, res, next. A guard receives an ExecutionContext — with getHandler() and getClass() —…
Three options, three distinct jobs: - whitelist: true — strips every property that has no validation decorator on the DTO. Prevents mass assignment (a client sneaking in isAdmin: true). - forbidNonWhitelisted: true — instead of silently stripping, throws 400 when an unknown property is present.…
The difference is whether dependency injection works. app.useGlobalFilters(new AllExceptionsFilter()) runs outside any module context, so you instantiate the filter yourself and wire its dependencies by hand. Such a filter cannot inject ConfigService, Logger, and so on. Registering via the APPFILTER token in a module's providers…
They differ in communication model. @MessagePattern — request-response (RPC). The client calls client.send(pattern, payload) and gets an Observable; whatever the handler returns is sent back. The client waits. @EventPattern — fire-and-forget. The client calls client.emit(pattern, payload) and does not wait; the handler's return value is…