☰ Mục lục series
Tài liệu NestJS tiếng Việt
  1. Nhập môn (Overview)
    1. Giới thiệu
    2. First steps
    3. Controllers
    4. Providers
    5. Modules
    6. Middleware
    7. Exception filters
    8. Pipes
    9. Guards
    10. Interceptors
    11. Custom decorators
  2. Nền tảng (Fundamentals)
    1. Custom providers
    2. Asynchronous providers
    3. Dynamic modules
    4. Injection scopes
    5. Circular dependency
    6. Module reference
    7. Lazy-loading modules
    8. Execution context
    9. Lifecycle events
    10. Discovery service
    11. Platform agnosticism
    12. Testing
  3. Kỹ thuật (Techniques)
    1. Configuration
    2. Database (SQL)
    3. MongoDB
    4. Validation
    5. Caching
    6. Serialization
    7. Versioning
    8. Task scheduling
    9. Queues
    10. Logging
    11. Cookies
    12. Events
    13. Compression
    14. File upload
    15. Streaming files
    16. HTTP module
    17. Session
    18. MVC
    19. Performance (Fastify)
    20. Server-Sent Events
  4. Bảo mật (Security)
    1. Authentication
    2. Authorization
    3. Encryption & Hashing
    4. Helmet
    5. CORS
    6. CSRF
    7. Rate limiting
    8. Vòng đời request
  5. OpenAPI (Swagger)
    1. Introduction
    2. Types and parameters
    3. Operations
    4. Security
    5. Mapped types
    6. Decorators
    7. CLI plugin
    8. Other features
  6. Recipes
    1. REPL
    2. CRUD generator
    3. SWC (fast compiler)
    4. Passport (auth)
    5. Hot reload
    6. MikroORM
    7. Router module
    8. Health checks (Terminus)
    9. CQRS
    10. Prisma
    11. Serve static
    12. Commander
    13. Async local storage
  7. WebSockets
    1. Gateways
    2. Exception filters
    3. Pipes
    4. Guards
    5. Interceptors
    6. Adapters
  8. Microservices
    1. Overview
    2. Redis
    3. MQTT
    4. NATS
    5. RabbitMQ
    6. Kafka
    7. gRPC
    8. Custom transporters
    9. Exception filters
    10. Pipes
    11. Pre-request hooks
    12. Guards
    13. Interceptors
  9. GraphQL
    1. Quick start
    2. Resolvers
    3. Mutations
    4. Subscriptions
    5. Scalars
    6. Directives
    7. Interfaces
    8. Unions and enums
    9. Field middleware
    10. Mapped types
    11. Plugins
    12. Complexity
    13. Extensions
    14. CLI plugin
    15. Generating SDL
    16. Sharing models
    17. Other features
    18. Federation
  10. CLI & triển khai
    1. CLI overview
    2. Workspaces
    3. Libraries
    4. Usage
    5. Scripts
    6. Deployment
    7. Standalone apps
  11. FAQ
    1. Serverless
    2. HTTP adapter
    3. Keep-Alive connections
    4. Global path prefix
    5. Raw body
    6. Hybrid application
    7. HTTPS & multiple servers
    8. Common errors
  12. Phụ lục
    1. Bảng thuật ngữ
Kỹ thuật (Techniques)

Hiệu năng (Performance) (Fastify)

Bản dịch từ docs.nestjs.com/techniques/performance

Theo mặc định, Nest dùng framework Express. Như đã đề cập trước đó, Nest cũng cung cấp khả năng tương thích với các thư viện khác, như Fastify. Nest đạt được sự độc lập với framework này bằng cách implement một framework adapter, có nhiệm vụ chính là proxy middleware và handler tới implementation cụ thể của từng thư viện.

Gợi ý Chú ý rằng để implement một framework adapter, thư viện đích phải cung cấp cơ chế xử lý request/response pipeline tương tự như những gì có trong Express.

Fastify là một framework thay thế tốt cho Nest vì nó giải quyết các vấn đề thiết kế theo cách tương tự Express. Tuy nhiên, Fastify nhanh hơn Express đáng kể, đạt gần gấp đôi kết quả benchmark. Vậy một câu hỏi hợp lý là, tại sao Nest lại dùng Express làm HTTP provider mặc định. Lý do là vì Express được dùng rộng rãi, được biết đến nhiều, và có một tập hợp middleware tương thích khổng lồ, có sẵn cho người dùng Nest ngay khi cài đặt.

Nhưng vì Nest cung cấp sự độc lập với framework, bạn có thể dễ dàng chuyển đổi giữa hai lựa chọn này. Fastify có thể là lựa chọn tốt hơn khi tốc độ thô (raw speed) là ưu tiên hàng đầu. Để dùng Fastify, chỉ cần chọn FastifyAdapter có sẵn như trong chương này.

Ghi chú người dịch Đây tương tự việc chọn giữa các web framework nhẹ ở Go (như net/http thuần hay fasthttp) hoặc giữa các driver HTTP khác nhau ở PHP — bản thân logic route/controller/middleware của ứng dụng không đổi, chỉ có lớp adapter bên dưới xử lý request/response là khác. Nest tách phần “core logic” (DI, decorator, module) ra khỏi phần “HTTP provider”, nên đổi Express sang Fastify về lý thuyết chỉ là đổi một dòng code ở main.ts — miễn là bạn không viết code phụ thuộc trực tiếp vào API riêng của Express (ví dụ req/res kiểu Express) ở nơi khác.

Cài đặt (Installation)

Đầu tiên, ta cần cài package cần thiết:

$ npm i --save @nestjs/platform-fastify

Adapter

Sau khi cài platform Fastify, ta có thể dùng FastifyAdapter.

import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter()
  );
  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();

Theo mặc định, Fastify chỉ listen trên interface localhost 127.0.0.1 (đọc thêm). Nếu bạn muốn nhận connection từ các host khác, bạn nên chỉ định '0.0.0.0' trong lệnh gọi listen():

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );
  await app.listen(3000, '0.0.0.0');
}

Package đặc thù theo platform (Platform specific packages)

Hãy nhớ rằng khi bạn dùng FastifyAdapter, Nest sẽ dùng Fastify làm HTTP provider. Điều này nghĩa là mỗi công thức (recipe) nào phụ thuộc vào Express có thể sẽ không còn hoạt động. Bạn nên dùng các package tương đương của Fastify thay thế.

Response redirect (Redirect response)

Fastify xử lý response redirect có khác biệt đôi chút so với Express. Để redirect đúng cách với Fastify, trả về cả status code và URL, như sau:

@Get()
index(@Res() res) {
  res.status(302).redirect('/login');
}

Option của Fastify (Fastify options)

Bạn có thể truyền option vào constructor của Fastify thông qua constructor của FastifyAdapter. Ví dụ:

new FastifyAdapter({ logger: true });

Middleware

Middleware function nhận vào req và res object thô (raw), thay vì các wrapper của Fastify. Đây là cách package middie hoạt động — package mà Fastify dùng bên dưới — xem thêm trang này để biết thêm thông tin.

import { Injectable, NestMiddleware } from '@nestjs/common';
import { FastifyRequest, FastifyReply } from 'fastify';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: FastifyRequest['raw'], res: FastifyReply['raw'], next: () => void) {
    console.log('Request...');
    next();
  }
}
import { Injectable } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware {
  use(req, res, next) {
    console.log('Request...');
    next();
  }
}

Ghi chú người dịch Đây là điểm khác biệt dễ gây bug nhất khi chuyển từ Express sang Fastify: middleware của Nest ở Fastify nhận req/res thô (Node.js native IncomingMessage/ServerResponse qua .raw) chứ không phải object Fastify đã được “làm giàu” (như request.query parse sẵn kiểu Fastify). Nếu bạn copy nguyên middleware viết cho Express sang mà không kiểm tra lại, rất dễ gặp lỗi vì API của raw request/response khác với API tiện lợi mà Express hay Fastify cung cấp ở tầng cao hơn.

Route Config

Bạn có thể dùng tính năng route config của Fastify với decorator @RouteConfig().

@RouteConfig({ output: 'hello world' })
@Get()
index(@Req() req) {
  return req.routeConfig.output;
}

Route Constraints

Từ v10.3.0, @nestjs/platform-fastify hỗ trợ tính năng route constraints của Fastify với decorator @RouteConstraints.

@RouteConstraints({ version: '1.2.x' })
newFeature() {
  return 'This works only for version >= 1.2.x';
}

Gợi ý @RouteConfig() và @RouteConstraints được import từ @nestjs/platform-fastify.

Ví dụ (Example)

Một ví dụ hoạt động thực tế có sẵn tại đây.

Nội dung gốc: NestJS Documentation © Kamil Myśliwiec, giấy phép MIT. Bản dịch và ghi chú: Lê Văn Dũng.