Chuyển đến nội dung chính

Lesson 3: Install and Initialize NestJS Project

Install NestJS CLI, create project, folder structure, understand important files. Run the development server and write the first API endpoint.

💻 Programming — Lesson 3 Lesson 3: Install and Initialize NestJS Project

NestJS: From Basics to Advanced

Part 1: NestJS Platform

xdev.asia

1. Install NestJS CLI

NestJS CLI is a command-line tool that helps you create, develop and maintain NestJS applications. CLI automatically generates boilerplate code, manages project structure, and runs the development server.

System requirements

  • Node.js >= 18.x (20 LTS or 22 LTS recommended)
  • npm >= 9.x or yarn >= 1.22 or pnpm >= 8.x
# Kiểm tra Node.js version
node --version  # v22.x.x

# Cài đặt NestJS CLI global
npm install -g @nestjs/cli

# Kiểm tra CLI version
nest --version  # 11.x.x

# Xem tất cả commands
nest --help

2. Initialize Project

# Tạo project mới
nest new my-nestjs-app

# CLI sẽ hỏi package manager
# ? Which package manager would you ❤️  to use?
#   npm
#   yarn
# ❯ pnpm

# Hoặc chỉ định sẵn
nest new my-nestjs-app --package-manager pnpm

# Tạo project với strict mode
nest new my-nestjs-app --strict

3. Folder structure

my-nestjs-app/
├── src/
│   ├── app.controller.ts       # Controller mẫu
│   ├── app.controller.spec.ts  # Unit test cho controller
│   ├── app.module.ts           # Root module
│   ├── app.service.ts          # Service mẫu
│   └── main.ts                 # Entry point
├── test/
│   ├── app.e2e-spec.ts         # E2E test
│   └── jest-e2e.json           # Jest E2E config
├── .eslintrc.js                # ESLint config
├── .prettierrc                 # Prettier config
├── nest-cli.json               # NestJS CLI config
├── package.json
├── tsconfig.json               # TypeScript config
└── tsconfig.build.json         # Build-specific TS config

4. Understand important files

main.ts — Entry Point

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  // Tạo NestJS application instance từ root module
  const app = await NestFactory.create(AppModule);
  
  // Cấu hình global prefix (optional)
  app.setGlobalPrefix('api/v1');
  
  // Bật CORS
  app.enableCors({
    origin: ['http://localhost:3000'],
    credentials: true,
  });
  
  // Lắng nghe trên port
  await app.listen(3000);
  console.log(`Application is running on: ${await app.getUrl()}`);
}
bootstrap();

app.module.ts — Root Module

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],       // Các module khác cần import
  controllers: [AppController],  // Controllers trong module này
  providers: [AppService],       // Services/Providers
})
export class AppModule {}

app.controller.ts — Sample controller

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()  // Route prefix: '' (root)
export class AppController {
  // AppService được inject tự động qua constructor
  constructor(private readonly appService: AppService) {}

  @Get()  // GET /
  getHello(): string {
    return this.appService.getHello();
  }
}

app.service.ts — Sample service

import { Injectable } from '@nestjs/common';

@Injectable()  // Đánh dấu class này có thể được inject
export class AppService {
  getHello(): string {
    return 'Hello World!';
  }
}

5. Run Development Server

# Development mode (watch mode - auto reload)
npm run start:dev

# Debug mode
npm run start:debug

# Production mode
npm run start:prod

# Output:
# [Nest] 12345  - 03/30/2026, 12:00:00 PM   LOG [NestFactory] Starting Nest application...
# [Nest] 12345  - 03/30/2026, 12:00:00 PM   LOG [InstanceLoader] AppModule dependencies initialized
# [Nest] 12345  - 03/30/2026, 12:00:00 PM   LOG [RoutesResolver] AppController {/}: +1ms
# [Nest] 12345  - 03/30/2026, 12:00:00 PM   LOG [RouterExplorer] Mapped {/, GET} route
# [Nest] 12345  - 03/30/2026, 12:00:00 PM   LOG [NestApplication] Nest application successfully started
# Test API
curl http://localhost:3000
# Hello World!

6. NestJS CLI Generate Commands

CLI can automatically generate code for you:

# Generate resource đầy đủ (CRUD)
nest generate resource users
# ? What transport layer do you use? REST API
# ? Would you like to generate CRUD entry points? Yes
# CREATE src/users/users.controller.ts
# CREATE src/users/users.module.ts
# CREATE src/users/users.service.ts
# CREATE src/users/dto/create-user.dto.ts
# CREATE src/users/dto/update-user.dto.ts
# CREATE src/users/entities/user.entity.ts

# Generate từng thành phần
nest g controller cats       # Controller
nest g service cats          # Service
nest g module cats           # Module
nest g guard auth            # Guard
nest g interceptor logging   # Interceptor
nest g pipe validation       # Pipe
nest g filter http-exception # Exception Filter
nest g middleware logger     # Middleware
nest g decorator roles       # Custom Decorator

# Viết tắt
nest g res products    # resource
nest g co products     # controller
nest g s products      # service
nest g mo products     # module

# Generate không test file
nest g s users --no-spec

# Dry run (xem trước, không tạo file)
nest g res orders --dry-run

7. Configure nest-cli.json

{
  "$schema": "https://json.schemastore.org/nest-cli",
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "deleteOutDir": true,
    "assets": ["**/*.graphql", "**/*.proto"],
    "watchAssets": true,
    "builder": "swc",
    "typeCheck": true
  },
  "generateOptions": {
    "spec": true,
    "flat": false
  }
}

Tip: From NestJS 10+, you can use it SWC builder instead of the default TypeScript compiler to build ~20x faster:

# Cài SWC
npm install --save-dev @swc/cli @swc/core

# Thêm vào nest-cli.json
# "builder": "swc"

8. Write the first API Endpoint

Create a simple Users module:

nest g res users --no-spec
// src/users/users.controller.ts
import { Controller, Get, Post, Body, Param, Delete } from '@nestjs/common';
import { UsersService } from './users.service';
import { CreateUserDto } from './dto/create-user.dto';

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.usersService.create(createUserDto);
  }

  @Get()
  findAll() {
    return this.usersService.findAll();
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.usersService.findOne(+id);
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.usersService.remove(+id);
  }
}
// src/users/users.service.ts
import { Injectable } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';

interface User {
  id: number;
  name: string;
  email: string;
}

@Injectable()
export class UsersService {
  private users: User[] = [
    { id: 1, name: 'Duy Tran', email: '[email protected]' },
    { id: 2, name: 'Alex Nguyen', email: '[email protected]' },
  ];

  create(dto: CreateUserDto): User {
    const user: User = { id: Date.now(), ...dto };
    this.users.push(user);
    return user;
  }

  findAll(): User[] {
    return this.users;
  }

  findOne(id: number): User | undefined {
    return this.users.find(u => u.id === id);
  }

  remove(id: number): void {
    this.users = this.users.filter(u => u.id !== id);
  }
}
# Test API
curl http://localhost:3000/users
# [{"id":1,"name":"Duy Tran","email":"[email protected]"},...]

curl -X POST http://localhost:3000/users \
  -H "Content-Type: application/json" \
  -d '{"name":"New User","email":"[email protected]"}'
# {"id":1711785600000,"name":"New User","email":"[email protected]"}

9. Summary

  • NestJS CLI helps scaffold projects quickly
  • Clear directory structure: main.ts → AppModule → Controllers + Services
  • nest generate resources create full CRUD in seconds
  • SWC builder speeds up building significantly

The next article will go deeper Controllers and Routing — how NestJS handles HTTP requests.