Установка и первый проект
Что понадобится
- Node.js 20+ (LTS).
- npm или pnpm.
- VS Code с расширениями.
- PostgreSQL или SQLite — для БД.
Nest CLI
Глобально:
npm install -g @nestjs/cli
nest --version
Или через npx — без установки:
npx @nestjs/cli new my-app
Создание проекта
nest new my-app
CLI спросит: какой пакетный менеджер (npm / yarn / pnpm).
Создаст:
my-app/
├── src/
│ ├── app.controller.spec.ts
│ ├── app.controller.ts
│ ├── app.module.ts
│ ├── app.service.ts
│ └── main.ts
├── test/
│ └── app.e2e-spec.ts
├── .eslintrc.js
├── .prettierrc
├── nest-cli.json
├── package.json
├── tsconfig.json
└── tsconfig.build.json
И запустит npm install.
Запуск
cd my-app
npm run start:dev
Открыть http://localhost:3000 — увидишь Hello World!.
Скрипты
package.json:
{
"scripts": {
"build": "nest build",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:e2e": "jest --config ./test/jest-e2e.json"
}
}
Основные:
start:dev— с hot reload.build— сборка вdist/.start:prod— прод-запуск.test— unit-тесты.
main.ts
Точка входа:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
console.log('Сервер: http://localhost:3000');
}
bootstrap();
Разбор:
NestFactory.create— создать приложение.AppModule— корневой модуль.app.listen(3000)— запустить.
app.module.ts
Корневой модуль:
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Метаданные модуля:
imports— другие модули.controllers— HTTP-контроллеры.providers— сервисы.exports— что отдавать наружу.
app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
}
constructor — DI: NestJS сам подставит AppService.
app.service.ts
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}
Первый роут
Добавим в контроллер:
@Get('users')
getUsers(): string[] {
return ['Иван', 'Мария'];
}
Проверка:
curl http://localhost:3000/users
# ["Иван","Мария"]
Nest CLI команды
Создать модуль:
nest g module users
Создать контроллер:
nest g controller users
Создать сервис:
nest g service users
Создать всё сразу (CRUD):
nest g resource users
Что создаст resource:
src/users/
├── dto/
│ ├── create-user.dto.ts
│ └── update-user.dto.ts
├── entities/
│ └── user.entity.ts
├── users.controller.ts
├── users.module.ts
├── users.service.ts
└── users.service.spec.ts
И автоматически подключит в AppModule.
Структура проекта
Рекомендую:
src/
├── main.ts
├── app.module.ts
├── common/
│ ├── decorators/
│ ├── filters/
│ ├── guards/
│ ├── interceptors/
│ └── pipes/
├── config/
│ └── configuration.ts
├── modules/
│ ├── users/
│ │ ├── dto/
│ │ ├── entities/
│ │ ├── users.controller.ts
│ │ ├── users.module.ts
│ │ └── users.service.ts
│ ├── auth/
│ └── posts/
└── shared/
└── services/
Каждая фича — модуль в modules/.
Запуск в watch-режиме
npm run start:dev
Что происходит:
- Компиляция TypeScript.
- Запуск сервера.
- Отслеживание изменений.
- Автоматическая перезагрузка.
Отладка в VS Code
.vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug NestJS",
"runtimeExecutable": "npm",
"runtimeArgs": ["run", "start:debug"],
"port": 9229,
"restart": true
}
]
}
F5 — запуск с breakpoints.
Переменные окружения
.env:
NODE_ENV=development
PORT=3000
DATABASE_URL=postgres://...
JWT_SECRET=secret
src/main.ts:
const port = Number(process.env.PORT) || 3000;
await app.listen(port);
В NestJS обычно через @nestjs/config:
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
],
})
export class AppModule {}
Чтение:
import { ConfigService } from '@nestjs/config';
constructor(private config: ConfigService) {
const port = this.config.get<number>('PORT', 3000);
}
Практика: мини-API
nest g resource users — создаст всё.
Заменим users.service.ts:
import { Injectable } from '@nestjs/common';
export interface User {
id: number;
name: string;
email: string;
}
@Injectable()
export class UsersService {
private users: User[] = [
{ id: 1, name: 'Иван', email: 'ivan@example.com' },
];
findAll(): User[] {
return this.users;
}
findOne(id: number): User | undefined {
return this.users.find(u => u.id === id);
}
create(user: Omit<User, 'id'>): User {
const newUser = { id: this.users.length + 1, ...user };
this.users.push(newUser);
return newUser;
}
}
Контроллер:
import { Controller, Get, Post, Body, Param } from '@nestjs/common';
import { UsersService, User } from './users.service';
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
findAll(): User[] {
return this.usersService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string): User | undefined {
return this.usersService.findOne(+id);
}
@Post()
create(@Body() user: Omit<User, 'id'>): User {
return this.usersService.create(user);
}
}
Проверка
curl http://localhost:3000/users
curl http://localhost:3000/users/1
curl -X POST http://localhost:3000/users \
-H 'Content-Type: application/json' \
-d '{"name":"Мария","email":"maria@example.com"}'
Итог
nest new— создать проект.start:dev— watch-режим.- CLI — генерирует модули, контроллеры, сервисы.
- Структура:
main.ts,app.module.ts, модули. nest g resource— CRUD из коробки.- DI — через конструктор.
ConfigModule— для env.- VS Code — встроенный debug.
Дальше — модули.