Пошук уроків, статей та іншого контенту
Ознайомитеся з призначенням NestJS, його перевагами та типовими сценаріями використання для серверних застосунків.
NestJS — це фреймворк для створення серверних застосунків на Node.js. Він написаний на TypeScript і допомагає будувати програми зі зрозумілою структурою.
За допомогою NestJS можна створювати:
REST API;
сервери для вебзастосунків;
мікросервіси;
GraphQL API;
застосунки, що працюють із базами даних;
сервери для оброблення подій і повідомлень.
NestJS використовує можливості Node.js, але додає до них готову архітектуру, модулі, контролери та систему залежностей.
Node.js дозволяє створювати сервери, але не змушує розробника організовувати код певним способом. У невеликому проєкті це не проблема. Проте зі зростанням застосунку можуть з’явитися такі труднощі:
логіка розподілена між різними файлами;
складно зрозуміти залежності між частинами програми;
код контролерів містить занадто багато відповідальності;
різні розробники організовують код по-різному;
тестування та розширення застосунку стають складнішими.
NestJS вирішує ці проблеми за допомогою вбудованих архітектурних правил і механізмів.
Основна ідея NestJS:
Кожна частина застосунку має чітку відповідальність і належить до відповідного модуля.
NestJS пропонує поділ застосунку на:
модулі;
контролери;
сервіси;
інші спеціалізовані компоненти.
Це спрощує навігацію по проєкту. Розробник одразу розуміє, де знаходиться обробник HTTP-запиту, де бізнес-логіка, а де конфігурація модуля.
NestJS розробляється з використанням TypeScript. Типи допомагають:
раніше знаходити помилки;
краще розуміти структуру даних;
отримувати підказки в редакторі;
безпечніше змінювати код.
NestJS можна використовувати і з JavaScript, але TypeScript є основним і рекомендованим варіантом.
NestJS активно використовує декоратори. Вони описують призначення класів і методів.
Наприклад:
@Controller('users')
export class UsersController {
@Get()
findAll() {
return [];
}
}У цьому прикладі:
@Controller('users') визначає контролер для адреси /users;
@Get() визначає обробник GET-запитів;
метод findAll виконується під час запиту GET /users.
NestJS має систему dependency injection — впровадження залежностей.
Замість того щоб створювати залежності вручну всередині класу, можна передати їх у конструктор:
constructor(private readonly usersService: UsersService) {}NestJS сам створить потрібний екземпляр UsersService і передасть його контролеру.
Це робить код:
менш залежним від конкретних реалізацій;
зручнішим для тестування;
простішим для повторного використання.
Модуль об’єднує пов’язані компоненти. Наприклад, функціональність користувачів може містити:
UsersController;
UsersService;
моделі користувачів;
налаштування доступу до даних.
Такий код можна зберігати в одному UsersModule.
Модуль — це клас із декоратором @Module. Він описує, які контролери, сервіси та інші модулі належать до певної частини застосунку.
Приклад:
@Module({
controllers: [UsersController],
providers: [UsersService],
})
export class UsersModule {}Властивість controllers містить контролери модуля, а providers — сервіси та інші залежності.
Кожен NestJS-застосунок має кореневий модуль. Зазвичай він називається AppModule.
Контролер приймає вхідні HTTP-запити та повертає відповіді.
@Controller('products')
export class ProductsController {
@Get()
findAll() {
return [
{ id: 1, name: 'Keyboard' },
{ id: 2, name: 'Mouse' },
];
}
}Цей контролер обробляє запит:
GET /productsі повертає список продуктів.
Контролер не повинен містити всю бізнес-логіку. Його завдання — отримати дані запиту, передати їх у потрібний сервіс і сформувати відповідь.
Сервіс містить логіку застосунку. Він створюється за допомогою декоратора @Injectable.
@Injectable()
export class ProductsService {
findAll() {
return [
{ id: 1, name: 'Keyboard' },
{ id: 2, name: 'Mouse' },
];
}
}Контролер може використовувати цей сервіс через впровадження залежності:
@Controller('products')
export class ProductsController {
constructor(private readonly productsService: ProductsService) {}
@Get()
findAll() {
return this.productsService.findAll();
}
}Такий поділ дозволяє залишити контролер простим, а логіку зберігати в сервісі.
Для створення нового проєкту використовують Nest CLI:
npm install -g @nestjs/cli
nest new hello-nest
cd hello-nest
npm run start:devПісля запуску NestJS створить сервер, який зазвичай доступний за адресою http://localhost:3000.
Замініть вміст файлів на такий приклад.
Файл src/app.service.ts:
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getGreeting(name: string) {
return {
message: `Привіт, ${name}!`,
};
}
}Файл src/app.controller.ts:
import { Controller, Get, Query } from '@nestjs/common';
import { AppService } from './app.service';
@Controller('hello')
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getGreeting(@Query('name') name?: string) {
return this.appService.getGreeting(name || 'світе');
}
}Файл src/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 {}Після запуску виконайте запит:
curl "http://localhost:3000/hello?name=Олено"Сервер поверне JSON:
{
"message": "Привіт, Олено!"
}У цьому прикладі:
AppController обробляє маршрут /hello.
@Get() визначає GET-запит.
@Query('name') отримує параметр name з URL.
AppService містить логіку формування привітання.
NestJS передає екземпляр AppService у контролер через конструктор.
NestJS часто використовують для серверної частини вебзастосунків. Контролери обробляють HTTP-запити, а сервіси виконують операції з даними.
Наприклад:
отримання списку товарів;
створення нового користувача;
оновлення профілю;
видалення замовлення.
NestJS може бути сервером для застосунків, створених за допомогою React, Angular, Vue або інших клієнтських технологій.
Клієнт надсилає запити до API, а NestJS:
перевіряє запит;
виконує бізнес-логіку;
працює з базою даних;
повертає результат.
NestJS має засоби для створення мікросервісів. Окремі частини великої системи можна розділити на незалежні сервіси.
Наприклад:
сервіс користувачів;
сервіс платежів;
сервіс повідомлень;
сервіс замовлень.
Кожен сервіс може мати власну відповідальність і взаємодіяти з іншими сервісами.
Структура NestJS особливо корисна, коли над проєктом працює кілька розробників. Єдині правила організації коду спрощують:
code review;
розподіл завдань;
пошук помилок;
додавання нових функцій;
підтримку проєкту.
NestJS працює поверх серверної платформи Node.js. За замовчуванням він використовує Express, але може працювати і з Fastify.
Важливо розуміти різницю:
Express — це мінімалістичний вебфреймворк;
NestJS — це фреймворк із готовою архітектурою та додатковими правилами.
Express дає більше свободи, але значну частину структури потрібно продумати самостійно. NestJS одразу пропонує спосіб організації застосунку.
NestJS також дозволяє використовувати можливості базової платформи, якщо вони потрібні.
NestJS добре підходить, якщо:
застосунок має багато функцій;
потрібна чітка структура проєкту;
команда використовує TypeScript;
важливі тестованість і підтримуваність;
планується розширення серверної частини;
потрібно створити REST API або мікросервіс.
Для маленького одноразового скрипту NestJS може бути зайвим, оскільки створення його структури потребує додаткових кроків. Але для повноцінного серверного застосунку організація, яку надає NestJS, зазвичай стає перевагою.
Контролер має обробляти запит і викликати потрібний сервіс. Якщо в ньому з’являється багато бізнес-логіки, код стає складним для тестування та підтримки.
Краще переносити основну логіку в сервіси.
providersЯкщо сервіс використовується модулем, він має бути зареєстрований у властивості providers:
@Module({
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}Без цього NestJS не зможе створити залежність для контролера.
controllersКонтролер також потрібно додати до відповідного модуля. Інакше NestJS не зареєструє його маршрути.
У прикладі:
@Controller('hello')
@Get()повний маршрут — /hello.
А параметр:
/hello?name=Оленоотримується через @Query('name'). Це не окремий маршрут, а значення з рядка запиту.
Якщо сервіс зареєстрований у модулі, не потрібно створювати його через new у контролері. Краще передати його в конструктор і дозволити NestJS керувати залежністю.
NestJS — фреймворк для створення серверних застосунків на Node.js.
Основною мовою NestJS є TypeScript.
Фреймворк пропонує структуровану архітектуру на основі модулів, контролерів і сервісів.
Контролери обробляють HTTP-запити.
Сервіси містять бізнес-логіку.
Модулі об’єднують пов’язані компоненти.
Впровадження залежностей спрощує використання сервісів і тестування.
NestJS підходить для REST API, серверів вебзастосунків, мікросервісів і великих командних проєктів.
Його головна перевага — передбачувана структура, яка спрощує розроблення та підтримку застосунку.