NestJS Case Studies & Practical Application 5 — Questions and Answers
Question 1: A NestJS app must support both REST and GraphQL endpoints for the same business logic. What is the best way to share service logic?
- Extract business logic into service classes injected into both REST controllers and GraphQL resolvers (Correct answer)
- Duplicate the logic in each controller and resolver separately
- Use REST internally and proxy all GraphQL queries to REST endpoints
- Build two separate NestJS apps and share logic via npm package
Correct answer: Extract business logic into service classes injected into both REST controllers and GraphQL resolvers
NestJS services are protocol-agnostic; injecting the same service into both a controller and a resolver eliminates duplication and keeps business logic in one place.
Question 2: During a load test, a NestJS app with Scope.REQUEST providers on hot paths shows poor throughput. What is the root cause?
- REQUEST-scoped providers create a new DI subtree for every request, adding instantiation overhead at high RPS (Correct answer)
- NestJS limits concurrent requests to 100 when using request scope
- The providers have circular dependencies introduced by request scope
- Request-scoped providers disable connection pooling in TypeORM
Correct answer: REQUEST-scoped providers create a new DI subtree for every request, adding instantiation overhead at high RPS
Every request triggers full instantiation of the provider and all its dependencies; at high throughput this overhead is significant compared to singleton reuse.
Question 3: A NestJS event-driven system uses EventEmitter2 internally. A bug causes some events to be lost silently. What is the most likely cause and fix?
- Event listeners are registered after the event is emitted; move listener registration to onModuleInit (Correct answer)
- EventEmitter2 drops events when there are more than 10 listeners
- The emit call must be awaited to guarantee delivery
- Events are lost because NestJS serializes them to JSON before dispatch
Correct answer: Event listeners are registered after the event is emitted; move listener registration to onModuleInit
If a module's listener is registered lazily after app bootstrap, events emitted during startup may fire before the listener exists.
Question 4: You are migrating a NestJS monolith to microservices. The first extracted service needs to communicate synchronously with the monolith. Which transport requires the least infrastructure change?
- TCP transport via @nestjs/microservices, since it requires no broker and works over the local network (Correct answer)
- NATS, because it is the NestJS default microservice transport
- gRPC, because it is the most performant option
- RabbitMQ, because it provides guaranteed delivery
Correct answer: TCP transport via @nestjs/microservices, since it requires no broker and works over the local network
TCP transport needs no external message broker — both sides open a socket, making it the fastest path to microservice extraction with minimal infrastructure.
Question 5: A NestJS app must rate-limit API endpoints per user, not per IP. Which implementation is correct?
- Use @nestjs/throttler with a custom ThrottlerGuard that overrides getTracker to return req.user.id (Correct answer)
- Use the default ThrottlerGuard which already uses user IDs
- Apply rate limiting in Nginx based on the Authorization header value
- Use a Redis INCR command in a controller method before business logic
Correct answer: Use @nestjs/throttler with a custom ThrottlerGuard that overrides getTracker to return req.user.id
Overriding getTracker in a custom ThrottlerGuard supplies req.user.id as the rate-limit key instead of the default IP address.
Question 6: A NestJS app's database queries slow down due to N+1 problems in a TypeORM relation. What resolves this without a full ORM rewrite?
- Use QueryBuilder with explicit leftJoinAndSelect to load relations in a single query (Correct answer)
- Add an index on every foreign key column
- Enable TypeORM's eager: true on all relations
- Batch requests with a setTimeout to collect multiple IDs
Correct answer: Use QueryBuilder with explicit leftJoinAndSelect to load relations in a single query
QueryBuilder with explicit JOINs fetches the parent and all related entities in one SQL statement, eliminating the extra query per record.
Question 7: A NestJS app's end-to-end tests fail intermittently because they share a single test database and run in parallel. What is the recommended fix?
- Isolate each test suite in its own database schema or use transactions that roll back after each test (Correct answer)
- Run all E2E tests serially with --runInBand and truncate tables between tests
- Mock the database in E2E tests to avoid conflicts
- Use a separate database server per developer machine
Correct answer: Isolate each test suite in its own database schema or use transactions that roll back after each test
Schema isolation or transaction rollback per test suite eliminates shared mutable state, the root cause of intermittent parallel test failures.
A NestJS app must support both REST and GraphQL endpoints for the same business logic.
What is the best way to share service logic?