☰ 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ữ
FAQ

Raw body (body thô)

Bản dịch từ docs.nestjs.com/faq/raw-body

Một trong những use case phổ biến nhất khi cần truy cập raw request body là thực hiện xác thực chữ ký webhook (webhook signature verification). Thông thường, để xác thực chữ ký webhook, bạn cần request body chưa qua serialize (unserialized) để tính toán hash HMAC.

Cảnh báo Tính năng này chỉ dùng được nếu middleware body parser toàn cục có sẵn của Nest được bật, tức là bạn không được truyền bodyParser: false khi tạo app.

Ghi chú người dịch Vì sao cần raw body thay vì req.body đã parse: chữ ký HMAC (ví dụ Stripe, GitHub webhook) được nhà cung cấp tính trên chuỗi byte gốc gửi đi. Sau khi body parser parse thành JSON object rồi JSON.stringify lại, thứ tự key hoặc khoảng trắng có thể khác với bản gốc, khiến hash tính lại không khớp — vì vậy phải giữ nguyên buffer byte thô để verify.

Dùng với Express

Trước tiên, bật tùy chọn này khi tạo Nest Express application:

import { NestFactory } from '@nestjs/core';
import type { NestExpressApplication } from '@nestjs/platform-express';
import { AppModule } from './app.module.js';

// trong hàm "bootstrap"
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
  rawBody: true,
});
await app.listen(process.env.PORT ?? 3000);

Để truy cập raw request body trong controller, Nest cung cấp sẵn interface tiện lợi RawBodyRequest để expose field rawBody trên request: dùng type RawBodyRequest:

import { Controller, Post, RawBodyRequest, Req } from '@nestjs/common';
import { Request } from 'express';

@Controller('cats')
class CatsController {
  @Post()
  create(@Req() req: RawBodyRequest<Request>) {
    const raw = req.rawBody; // trả về một `Buffer`.
  }
}

Đăng ký một parser khác

Mặc định, chỉ có parser json và urlencoded được đăng ký. Nếu muốn đăng ký một parser khác, bạn cần làm điều đó tường minh.

Ví dụ, để đăng ký parser text, bạn có thể dùng đoạn code sau:

app.useBodyParser('text');

Cảnh báo Đảm bảo bạn truyền đúng application type cho lời gọi NestFactory.create. Với Express application, type đúng là NestExpressApplication. Nếu không, phương thức .useBodyParser sẽ không tồn tại.

Giới hạn kích thước body parser

Nếu application của bạn cần parse body lớn hơn mức mặc định 100kb của Express, dùng cách sau:

app.useBodyParser('json', { limit: '10mb' });

Phương thức .useBodyParser sẽ tôn trọng tùy chọn rawBody được truyền trong application options.

Dùng với Fastify

Trước tiên, bật tùy chọn này khi tạo Nest Fastify application:

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

// trong hàm "bootstrap"
const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
  {
    rawBody: true,
  },
);
await app.listen(process.env.PORT ?? 3000);

Để truy cập raw request body trong controller, Nest cung cấp sẵn interface tiện lợi RawBodyRequest để expose field rawBody trên request: dùng type RawBodyRequest:

import { Controller, Post, RawBodyRequest, Req } from '@nestjs/common';
import { FastifyRequest } from 'fastify';

@Controller('cats')
class CatsController {
  @Post()
  create(@Req() req: RawBodyRequest<FastifyRequest>) {
    const raw = req.rawBody; // trả về một `Buffer`.
  }
}

Đăng ký một parser khác

Mặc định, chỉ có parser application/json và application/x-www-form-urlencoded được đăng ký. Nếu muốn đăng ký một parser khác, bạn cần làm điều đó tường minh.

Ví dụ, để đăng ký parser text/plain, bạn có thể dùng đoạn code sau:

app.useBodyParser('text/plain');

Cảnh báo Đảm bảo bạn truyền đúng application type cho lời gọi NestFactory.create. Với Fastify application, type đúng là NestFastifyApplication. Nếu không, phương thức .useBodyParser sẽ không tồn tại.

Giới hạn kích thước body parser

Nếu application của bạn cần parse body lớn hơn mức mặc định 1MiB của Fastify, dùng cách sau:

const bodyLimit = 10_485_760; // 10MiB
app.useBodyParser('application/json', { bodyLimit });

Phương thức .useBodyParser sẽ tôn trọng tùy chọn rawBody được truyền trong application options.

Ghi chú người dịch Để ý tên option khác nhau giữa hai adapter: Express dùng limit (chuỗi như '10mb'), còn Fastify dùng bodyLimit (số byte thuần). Nhầm lẫn giữa hai adapter khi đổi platform là lỗi khá dễ gặp.

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.