Tổng hợp 59 câu hỏi phỏng vấn NestJS kèm đáp án chi tiết, song ngữ Việt–Anh — sắp xếp từ cơ bản đến nâng cao. Ôn luyện miễn phí, tự động lưu tiến độ.
NestJS là framework Node.js TypeScript-first lấy cảm hứng từ Angular, tổ chức code theo Modules, Controllers và Providers (thường là Services) với Dependency Injection tích hợp sẵn. Nó không thay thế Express/Fastify mà chạy trên một trong hai adapter đó và thêm lớp abstraction để…
Module là đơn vị tổ chức cơ bản trong NestJS, nhóm các thành phần liên quan lại. Mỗi app có ít nhất một root module (AppModule). @Module() nhận một object với 4 thuộc tính: imports (modules khác cần dùng), controllers (xử lý HTTP requests), providers…
Controller chịu trách nhiệm nhận HTTP requests và trả về responses. Controller map routes đến handler methods thông qua decorators. @Controller('users') đặt base route /users. Các HTTP method decorators: @Get(), @Post(), @Patch(), @Put(), @Delete(). Có thể thêm path vào decorator như @Get(':id') để tạo route…
Provider là bất kỳ class nào được annotate với @Injectable() — services, repositories, factories, helpers. NestJS quản lý vòng đời và inject chúng tự động thông qua constructor injection. Cách hoạt động: khai báo provider trong providers array của module, NestJS IoC container tạo instance…
NestJS xử lý request qua pipeline theo thứ tự cố định: Middleware chạy đầu tiên (logging, CORS, session — access raw req/res), tiếp theo Guards kiểm tra authorization (trả về true/false), rồi Interceptors pre-processing (transform request trước khi vào handler), sau đó Pipes validate và…
Guards quyết định request có được phép đi tiếp không (authorization). Khác với Middleware, Guards implement interface CanActivate và có access vào ExecutionContext — biết được handler nào sẽ được gọi, rất hữu ích cho role-based access control. JWT Auth Guard hoạt động: extract Bearer…
Pipes có hai use-case chính: validation (throw exception nếu data không hợp lệ) và transformation (chuyển đổi input sang dạng mong muốn). Pipes implement interface PipeTransform với method transform(value, metadata). ValidationPipe của NestJS kết hợp với class-validator để validate DTO tự động. Cấu hình quan…
Interceptors wrap việc thực thi handler, cho phép chạy code trước và sau handler. Chúng implement NestInterceptor với method intercept(context, next) trả về Observable. Gọi next.handle() để tiếp tục pipeline, dùng RxJS operators để transform. Use-cases phổ biến: Response transform — dùng map() để wrap…
Exception Filters bắt các exceptions được throw trong ứng dụng và format response lỗi. NestJS có built-in filter xử lý HttpException và các subclass của nó. Nếu exception không phải HttpException, NestJS trả về 500 Internal Server Error mặc định. Custom global filter implement ExceptionFilter…
TypeORM là một trong những ORM phổ biến nhất với NestJS (Prisma cũng được ưa chuộng trong các project mới), sử dụng Data Mapper pattern thông qua Repository. Setup với TypeOrmModule.forRoot() trong AppModule cấu hình connection (type, host, port, credentials, entities path), synchronize: false trong…
JWT Auth flow gồm hai phần chính: AuthService xác thực credentials và cấp token, JwtStrategy/Guard bảo vệ routes. Cài đặt @nestjs/jwt, @nestjs/passport, passport, passport-jwt, bcryptjs. Tạo AuthModule import JwtModule.registerAsync() với ConfigService để lấy JWTSECRET và expiresIn. AuthService có method login(): tìm user theo email, compare…
@nestjs/config giúp quản lý environment variables an toàn với type-safety. ConfigModule.forRoot() với isGlobal: true cho phép inject ConfigService ở bất kỳ module nào mà không cần import lại. Validation schema với Joi: validationSchema: Joi.object({ PORT: Joi.number().default(3000), JWTSECRET: Joi.string().min(32).required() }) — app sẽ fail ngay khi…
NestJS dùng Jest và cung cấp Test.createTestingModule() để tạo test environment với DI container đầy đủ. Unit test service: tạo mock repository với jest.fn() cho mỗi method, đăng ký trong module với { provide: getRepositoryToken(Entity), useValue: mockRepo }. Test từng method riêng lẻ, verify calls…
Prisma là ORM thế hệ mới với type-safety chặt, ngày càng được ưa dùng thay TypeORM. Schema định nghĩa trong prisma/schema.prisma với cú pháp riêng, prisma generate tạo Prisma Client type-safe hoàn toàn. Setup NestJS: tạo PrismaService extends PrismaClient implements OnModuleInit, gọi this.$connect() trong onModuleInit().…
NestJS tích hợp Multer qua @nestjs/platform-express để xử lý multipart/form-data. Không cần install thêm gì với Express adapter. Upload single file: dùng @UseInterceptors(FileInterceptor('fieldName', options)) và @UploadedFile() decorator. Options quan trọng: storage — diskStorage() lưu disk hoặc memoryStorage() lưu buffer (dùng khi upload S3), fileFilter để…
Custom Decorators giúp code sạch hơn và tái sử dụng được. NestJS cung cấp createParamDecorator cho param decorators và SetMetadata để đính kèm metadata. @CurrentUser: dùng createParamDecorator((data, ctx) = ctx.switchToHttp().getRequest().user). Có thể nhận tham số để extract field cụ thể: @CurrentUser('email') trả về user.email, @CurrentUser()…
NestJS tích hợp Swagger qua @nestjs/swagger. Setup trong main.ts: DocumentBuilder cấu hình title/description/version/auth, SwaggerModule.createDocument() tạo document, SwaggerModule.setup('api/docs', app, document) serve UI. Annotations trên DTO: @ApiProperty({ example, description }) cho required fields, @ApiPropertyOptional() cho optional fields. Hỗ trợ enum, type, minLength, maxLength, default. Annotations trên Controller:…
NestJS có 3 provider scopes kiểm soát vòng đời instance: DEFAULT (Singleton): một instance dùng cho toàn app — đây là default và phổ biến nhất. Phù hợp cho stateless services như DatabaseService, ConfigService. REQUEST: tạo instance mới cho mỗi incoming request, bị destroy sau…
Dynamic modules cho phép configure module lúc runtime với tham số — khác static modules cấu hình cứng trong code. forRoot(options) là synchronous factory nhận options và trả về DynamicModule. forRootAsync(options) hỗ trợ async config như đọc từ ConfigService: Dùng trong AppModule: Pattern này dùng…
Custom providers cho phép kiểm soát cách NestJS tạo và inject dependencies: useValue: inject giá trị cụ thể — thường dùng cho config objects, mocking trong tests: useClass: chỉ định class khác để inject — dùng để swap implementation (mock, stub): useFactory: factory function tạo…
ExecutionContext extends ArgumentsHost, cung cấp thông tin về execution context hiện tại (HTTP, WebSocket, RPC). Guards, Interceptors và Exception Filters đều nhận ExecutionContext. Các methods quan trọng: - getType(): trả về 'http' 'ws' 'rpc' - switchToHttp(): trả về HttpArgumentsHost với getRequest(), getResponse() - switchToWs(): trả…
Transactions đảm bảo multiple DB operations thành công hoặc rollback toàn bộ. Cách 1 — QueryRunner (recommend cho complex transactions): Cách 2 — EntityManager.transaction() (cleaner cho simple cases): Cách 3 — @Transaction decorator (deprecated trong TypeORM 0.3+, không dùng). Lưu ý: không mix repository từ…
Repository API (High-level): phù hợp cho CRUD đơn giản, dễ đọc, type-safe: Query Builder (Low-level): cho queries phức tạp với dynamic conditions, subqueries, raw SQL expressions: Dùng Repository API cho 80% cases. Dùng Query Builder khi: complex JOINs, aggregations (COUNT/SUM/AVG), dynamic WHERE conditions, raw SQL…
Helmet: HTTP security headers middleware — ngăn chặn XSS, clickjacking, sniffing: CORS: chỉ allow origins cụ thể: Rate Limiting với @nestjs/throttler: Input sanitization: class-validator + ValidationPipe với whitelist: true ngăn chặn mass assignment. Dùng sanitize-html cho user-generated content. SQL Injection: TypeORM parameterized queries tự động…
JWT (Stateless): token mang đủ thông tin, server không cần lưu state. Phù hợp: - Microservices và distributed systems - Mobile apps (localStorage/SecureStorage) - Stateless REST APIs - Cross-domain authentication Sessions (Stateful): server lưu session data (DB hoặc Redis), client chỉ giữ session ID trong…
Unit tests trong NestJS isolate một class bằng cách mock tất cả dependencies. Pattern chuẩn với Test.createTestingModule(): Dùng jest.spyOn() để spy mà không replace hoàn toàn. Dùng jest.clearAllMocks() trong afterEach để reset state.
E2E tests test toàn bộ HTTP flow từ request đến response mà không cần real external services. Best practices: dùng test database thực (SQLite in-memory hoặc test Postgres), seed data trong beforeAll, cleanup trong afterAll. Chạy E2E riêng biệt với jest --testPathPattern=e2e.
NestJS cung cấp @nestjs/event-emitter (wrapper của EventEmitter2) cho internal events — không phải distributed messaging mà là in-process pub/sub. Async events: @OnEvent('order.created', { async: true }) để handler chạy async không block emitter. Dùng cho: decoupling business logic (sau khi create order, nhiều services cần…
Offset-based (skip/take): đơn giản, hỗ trợ random page access: Nhược điểm: không ổn định khi data thay đổi real-time, chậm khi skip lớn (DB phải scan). Cursor-based (keyset pagination): ổn định hơn cho real-time feeds, hiệu quả hơn khi scale: Dùng offset cho: admin dashboards,…
class-transformer cùng với ClassSerializerInterceptor tự động serialize/exclude fields trong response. Exclude sensitive fields (password, tokens): Enable globally: Controller return entity: Lưu ý: plain objects không bị transform — phải trả về instance của entity class để decorator có effect.
TypeORM cung cấp decorators tiện lợi cho timestamps và soft delete: Soft delete với TypeORM: Lưu ý: @DeleteDateColumn chỉ hoạt động khi dùng softDelete() và softRemove() — không phải delete() hay remove().
Connection pooling và query optimization là hai yếu tố quan trọng nhất để NestJS app chịu tải tốt ở production. Connection Pooling với TypeORM: Query optimization: 1. Dùng select để chỉ lấy columns cần thiết 2. Tạo indexes trên foreign keys và frequently queried columns…
NestJS không có registry provider toàn cục: mỗi module là một phạm vi DI riêng. Muốn OrderService (ở OrderModule) inject được UserService (ở UserModule) thì phải đủ hai vế: 1. UserModule export UserService. 2. OrderModule import UserModule. Đọc thông báo lỗi: dấu ? cho biết…
Middleware chạy trước khi router xác định handler nào sẽ được gọi, nên nó không biết route handler đích là hàm nào và không đọc được metadata gắn trên handler đó. Middleware chỉ có req, res, next như Express thông thường. Guard thì nhận ExecutionContext…
Ba option giải quyết ba việc khác nhau: - whitelist: true — loại bỏ mọi property không có decorator validation trong DTO. Chống mass assignment (client gửi kèm isAdmin: true). - forbidNonWhitelisted: true — thay vì âm thầm loại bỏ thì ném 400 khi có…
Khác nhau ở khả năng dùng dependency injection. app.useGlobalFilters(new AllExceptionsFilter()) chạy bên ngoài mọi module context, nên bạn phải tự new instance và tự truyền dependency. Filter đó không inject được ConfigService, Logger... (LoggerService là interface, không inject theo type được — phải dùng class…
Khác nhau ở mô hình giao tiếp. @MessagePattern — request-response (RPC). Client gọi client.send(pattern, payload), nhận về một Observable; giá trị handler trả về được gửi ngược lại cho client. Client chờ kết quả. @EventPattern — fire-and-forget. Client gọi client.emit(pattern, payload), không chờ; giá trị…