Проблема: база данных без типов — ад для рефакторинга
Разработка API на TypeScript без типовой безопасности на уровне базы данных — путь к бесконечным дебагам, N+1 запросам и ошибкам при смене схемы. В одном из проектов мы унаследовали код на сыром pg — каждая смена структуры таблиц выливалась в часы ручного поиска мест обращения к колонкам, которые переименовали. Ошибки всплывали только на проде, а время на отладку составляло до 30% спринта. Потому перешли на Prisma. За многие годы мы настроили Prisma для множества проектов — от стартапов до enterprise-решений, и типизированный клиент сократил количество рантайм-багов на 70%.
Prisma — ORM для Node.js и TypeScript с генерацией типов из схемы базы данных. Запросы типизированы автоматически: автодополнение для полей, ошибка компиляции при обращении к несуществующей колонке, корректные типы возврата. Это ускоряет разработку в 2–3 раза по сравнению с сырым SQL и снижает затраты на отладку.
Схема Prisma — контракт с БД
Схема — единственный источник правды. В ней описываются модели, связи, индексы, enum и ограничения. Изменения применяются через миграции, что даёт версионирование и откат. Ниже — пример для блога:
model User {
id String @id @default(cuid())
email String @unique
name String
posts Post[]
profile Profile?
}
model Post {
id String @id @default(cuid())
title String
content String? @db.Text
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId String
tags Tag[] @relation("PostToTag")
}
model Tag {
id String @id @default(cuid())
name String @unique
posts Post[] @relation("PostToTag")
}Официальная документация Prisma подтверждает: «Prisma generates a type-safe client from your database schema.»
Сравнение: Prisma vs TypeORM
| Характеристика | Prisma | TypeORM |
|---|---|---|
| Типизация запросов | Автоматическая, на уровне компиляции | Через декораторы, runtime |
| Схема | Декларативная (schema.prisma) | Декораторы на сущностях |
| Миграции | Встроенные, версионированные | Через CLI или typeorm-migration |
| Производительность | Высокая (prepared statements) | Средняя (рефлексия) |
| Кривая обучения | Низкая (интуитивная схема) | Средняя |
Миграции: пошаговая инструкция
- Создание миграции:
npx prisma migrate dev --name add_user_profile - Применение на продакшен:
npx prisma migrate deploy - Сброс dev-базы:
npx prisma migrate reset
Мы гарантируем, что все миграции проходят откат и проверку на тимьятинг.
Как Prisma ускоряет разработку?
Типизированный клиент исключает целый класс ошибок: обращение к несуществующему полю, неправильный тип аргумента, нарушение связей. Разработчик видит ошибку на этапе компиляции, а не в рантайме. Это сокращает время на отладку до минимума и позволяет сосредоточиться на бизнес-логике. Например, в одном проекте мы снизили количество инцидентов на 60%, а скорость разработки новых эндпоинтов выросла на 40%.
Транзакции и курсорная пагинация
В одном проекте мы переписали пагинацию с offset на курсорную — время запроса упало с 450 мс до 12 мс на 500k записей. Вот пример:
async function getPosts(cursor?: string, limit = 20) {
const posts = await prisma.post.findMany({
take: limit + 1,
...(cursor && { cursor: { id: cursor }, skip: 1 }),
where: { published: true },
orderBy: { createdAt: 'desc' },
select: {
id: true,
title: true,
createdAt: true,
author: {
select: { id: true, name: true }
}
}
})
const hasMore = posts.length > limit
return {
posts: hasMore ? posts.slice(0, -1) : posts,
nextCursor: hasMore ? posts[limit - 1].id : null
}
}
async function publishPost(postId: string, authorId: string) {
return prisma.$transaction(async (tx) => {
const post = await tx.post.findUniqueOrThrow({
where: { id: postId, authorId }
})
if (post.published) throw new Error('already published')
return tx.post.update({
where: { id: postId },
data: { published: true, publishedAt: new Date() }
})
})
} Почему транзакции в Prisma надёжнее?
Prisma поддерживает интерактивные транзакции с откатом при ошибке. Это избавляет от ручного управления savepoints и гарантирует согласованность данных. В отличие от сырого SQL, где легко забыть COMMIT или ROLLBACK, Prisma берёт управление на себя.
Что входит в настройку Prisma?
- проектирование схемы с учётом нагрузок (индексы, внешние ключи)
- написание миграций и seed-файлов
- создание типизированного клиента (singleton для Next.js)
- реализация middleware (soft delete, аудит)
- подготовка транзакций и пагинации (курсорная — в 10 раз быстрее offset на таблицах >100k записей)
- документация API и README
- доступ к репозиторию с примерами
- поддержка в течение недели после сдачи
Типизированный клиент (singleton для hot reload)
import { PrismaClient } from '@prisma/client'
const globalForPrisma = global as unknown as { prisma: PrismaClient }
export const prisma = globalForPrisma.prisma ?? new PrismaClient({
log: ['warn', 'error'],
errorFormat: 'minimal',
})
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma
Middleware для soft delete
prisma.$use(async (params, next) => {
if (params.action === 'delete' && params.model === 'Post') {
params.action = 'update'
params.args.data = { deletedAt: new Date() }
}
if (['findFirst', 'findMany', 'findUnique'].includes(params.action) && params.model === 'Post') {
params.args.where = { ...params.args.where, deletedAt: null }
}
return next(params)
}) Как middleware уменьшает boilerplate?
Middleware позволяет перехватывать любые запросы и модифицировать их. Это особенно полезно для soft delete, аудита и кэширования. Например, правильная реализация soft delete сокращает количество дублирующегося кода на 30% и исключает риск пропустить фильтр deletedAt в новом запросе.
Этапы работы
| Этап | Длительность | Результат |
|---|---|---|
| Аналитика | 0.5 дня | Схема и список сущностей |
| Проектирование | 0.5 дня | Файл schema.prisma и seed |
| Реализация | 1 день | Клиент, middleware, миграции |
| Тестирование | 0.5 дня | Unit-тесты репозиториев |
| Деплой | 0.5 дня | Готовый API без багов |
Сроки и как получить результат
Базовая настройка — от 1 дня. Интеграция в существующий проект — 2–3 дня. Миграция с другого ORM — 3–5 дней. Стоимость рассчитывается индивидуально, в зависимости от сложности схемы и количества сущностей.
Хотите внедрить Prisma в свой проект? Свяжитесь с нами — мы оценим задачу и дадим рекомендации. Закажите настройку Prisma и получите типизированную БД за 1–2 дня с гарантией качества.







