Пошук уроків, статей та іншого контенту
Встановимо Prisma, опишемо модель даних і підключимо ORM до проєкту NestJS.
Prisma — ORM для Node.js і TypeScript. Вона дає змогу:
описувати структуру бази даних у файлі schema.prisma;
створювати міграції;
генерувати типізований клієнт для роботи з базою;
виконувати запити до бази без написання SQL у більшості випадків.
У NestJS Prisma зазвичай підключають як окремий сервіс, який потім використовують в інших сервісах застосунку.
У цьому уроці ми:
встановимо Prisma;
створимо модель User;
налаштуємо SQLite;
виконаємо міграцію;
підключимо PrismaService до NestJS;
створимо простий endpoint для роботи з користувачами.
Передбачається, що у вас уже є NestJS-проєкт. Якщо його ще немає, створіть його:
nest new prisma-nest-app
cd prisma-nest-appВстановіть Prisma як залежність для розробки та Prisma Client як основну залежність:
npm install prisma --save-dev
npm install @prisma/clientІніціалізуйте Prisma з SQLite:
npx prisma init --datasource-provider sqliteПісля цього з’являться:
папка prisma;
файл prisma/schema.prisma;
файл .env.
SQLite зручна для навчання, тому що не потребує окремого сервера бази даних. У реальному проєкті можна використовувати PostgreSQL, MySQL або іншу підтримувану базу.
Відкрийте файл prisma/schema.prisma і замініть його вміст:
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
name String
email String @unique
createdAt DateTime @default(now())
}Блок datasource описує підключення до бази даних:
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}provider визначає тип бази даних;
url отримує адресу бази зі змінної оточення DATABASE_URL.
Блок generator визначає, що Prisma має згенерувати Prisma Client:
generator client {
provider = "prisma-client-js"
}Модель User описує таблицю користувачів:
model User {
id Int @id @default(autoincrement())
name String
email String @unique
createdAt DateTime @default(now())
}Тут:
id — числовий первинний ключ;
@id позначає первинний ключ;
@default(autoincrement()) автоматично збільшує значення id;
email — унікальне поле;
@default(now()) автоматично встановлює поточну дату й час.
Переконайтеся, що файл .env містить:
DATABASE_URL="file:./dev.db"Для SQLite це означає, що база даних зберігатиметься у файлі dev.db у папці prisma.
Тепер створимо таблицю User у базі даних:
npx prisma migrate dev --name initКоманда виконає кілька дій:
створить SQL-міграцію;
застосує її до бази даних;
згенерує Prisma Client.
Міграції зберігатимуться у папці prisma/migrations. Їх потрібно додавати до системи контролю версій разом із кодом проєкту.
Якщо Prisma Client потрібно згенерувати окремо, використовуйте:
npx prisma generateСтворимо модуль, який буде відповідати за Prisma:
nest g module prisma
nest g service prismaВідкрийте src/prisma/prisma.service.ts:
import {
Injectable,
OnModuleDestroy,
OnModuleInit,
} from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService
extends PrismaClient
implements OnModuleInit, OnModuleDestroy
{
async onModuleInit(): Promise<void> {
await this.$connect();
}
async onModuleDestroy(): Promise<void> {
await this.$disconnect();
}
}PrismaService наслідує PrismaClient, тому він має всі методи Prisma для роботи з моделями.
Метод onModuleInit викликається під час запуску NestJS і відкриває підключення до бази.
Метод onModuleDestroy викликається під час завершення роботи застосунку та закриває підключення.
Відкрийте src/prisma/prisma.module.ts:
import { Global, Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';
@Global()
@Module({
providers: [PrismaService],
exports: [PrismaService],
})
export class PrismaModule {}Декоратор @Global() робить модуль глобальним. Завдяки цьому PrismaService можна використовувати в інших модулях без повторного додавання PrismaModule до кожного imports.
Властивості providers та exports мають різні призначення:
providers реєструє сервіс у модулі;
exports дозволяє використовувати сервіс в інших модулях.
Підключіть PrismaModule в src/app.module.ts:
import { Module } from '@nestjs/common';
import { PrismaModule } from './prisma/prisma.module';
@Module({
imports: [PrismaModule],
})
export class AppModule {}Створимо модуль, сервіс і контролер для користувачів:
nest g module users
nest g service users
nest g controller usersВідкрийте src/users/users.service.ts:
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
@Injectable()
export class UsersService {
constructor(private readonly prisma: PrismaService) {}
async findAll() {
return this.prisma.user.findMany({
orderBy: {
createdAt: 'desc',
},
});
}
async create(name: string, email: string) {
return this.prisma.user.create({
data: {
name,
email,
},
});
}
}Prisma Client створює властивість user на основі моделі User у schema.prisma.
Метод findMany отримує список користувачів:
this.prisma.user.findMany()Метод create створює нового користувача:
this.prisma.user.create({
data: {
name,
email,
},
})Дані, які передаються в data, перевіряються TypeScript-типами, згенерованими Prisma.
Відкрийте src/users/users.controller.ts:
import { Body, Controller, Get, Post } from '@nestjs/common';
import { UsersService } from './users.service';
interface CreateUserBody {
name: string;
email: string;
}
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
findAll() {
return this.usersService.findAll();
}
@Post()
create(@Body() body: CreateUserBody) {
return this.usersService.create(body.name, body.email);
}
}Тепер контролер має два endpoint-и:
GET /users — отримує всіх користувачів;
POST /users — створює нового користувача.
Переконайтеся, що UsersModule містить сервіс і контролер:
import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
@Module({
controllers: [UsersController],
providers: [UsersService],
})
export class UsersModule {}Також додайте UsersModule до src/app.module.ts:
import { Module } from '@nestjs/common';
import { PrismaModule } from './prisma/prisma.module';
import { UsersModule } from './users/users.module';
@Module({
imports: [PrismaModule, UsersModule],
})
export class AppModule {}Запустіть NestJS у режимі розробки:
npm run start:devСтворіть користувача за допомогою curl:
curl -X POST http://localhost:3000/users \
-H "Content-Type: application/json" \
-d '{"name":"Олена","email":"olena@example.com"}'У відповідь ви отримаєте створений запис:
{
"id": 1,
"name": "Олена",
"email": "olena@example.com",
"createdAt": "2026-09-01T10:00:00.000Z"
}Отримайте список користувачів:
curl http://localhost:3000/usersПісля виконання запитів дані зберігатимуться у файлі SQLite-бази.
Для перегляду даних можна скористатися Prisma Studio:
npx prisma studioPrisma Studio відкриє вебінтерфейс для перегляду та редагування записів бази даних.
Під час зміни моделі даних використовуйте такий порядок:
змініть модель у prisma/schema.prisma;
створіть міграцію;
згенеруйте Prisma Client, якщо це потрібно;
використовуйте оновлену модель у сервісах NestJS.
Наприклад, додамо до користувача поле isActive:
model User {
id Int @id @default(autoincrement())
name String
email String @unique
isActive Boolean @default(true)
createdAt DateTime @default(now())
}Після зміни схеми створіть нову міграцію:
npx prisma migrate dev --name add-user-statusНе змінюйте структуру бази вручну, якщо для цього можна створити міграцію. Так історія змін бази залишатиметься синхронізованою з кодом проєкту.
Якщо TypeScript не знаходить PrismaClient або моделі, виконайте:
npx prisma generateDATABASE_URLПеревірте, що у корені проєкту є файл .env:
DATABASE_URL="file:./dev.db"Якщо таблиця User не існує, виконайте:
npx prisma migrate dev --name initPrismaService не можна впровадитиПеревірте, що:
PrismaService є у providers модуля;
PrismaService є у exports;
PrismaModule підключений до AppModule;
у сервісі використовується правильний імпорт:
import { PrismaService } from '../prisma/prisma.service';Поле email має атрибут @unique, тому два користувачі не можуть мати однакову адресу. Повторне створення користувача з тим самим email завершиться помилкою Prisma.
У цьому уроці ми:
встановили prisma та @prisma/client;
створили Prisma-схему з моделлю User;
налаштували SQLite через DATABASE_URL;
створили й застосували міграцію;
реалізували PrismaService;
підключили Prisma до NestJS через модуль;
використали Prisma у сервісі для створення та отримання користувачів.
Основний принцип інтеграції такий: Prisma описує моделі й працює з базою, а NestJS організовує ці операції у модулях, сервісах і контролерах.