Prisma без кліента Prisma: запиты Kysely захіщаныя ад помылак у Next.js
Выучыце, як выкарыстоўваць Prisma для працы з схемамі, ствараць типы Kysely за дапамою prisma-kysely, выбраць діалект Neon або pg, і безпечна выконваць запиты з коду сервера Next.js.
Крыніцы: **Using Prisma for Schema and Kysely for Queries in a Next.js App**
Prisma ўзначны для дизайну схемы, але Prisma Client ўтварае значную залежнасць, якая патрэбна для ўключэння ў кожную функцыю без сервера, калі вам проста трэба SQL з падтрымкай типаў. Практычны спосаб раздзелення: Prisma керуе схемай пад час розработы, генератор ператварае яе на типы TypeScript, а Kysely выкананяе запиты ў режыме працы. Шэрыфакс показвае, як установіць гэта ў проекте Next.js App Router, і параганяе дыалект Neon HTTP з класычным pg pool.
Якщо вы хочаце традыцыйны падход з Prisma Client у час выканання, адзірніце інструкцыю па налаштаванні Prisma 7 у проекте Next.js 16.
Як дзеляцца адпаведальнасці
Кожны інструмент у гэйму мае адну чыткую задачу:
- Prisma адмініструеяць кантэкст базы дадзеных: файл схемы, сінхронізацыю чыста міграцыю базы дадзеных, а таксама інструменты, такія як Prisma Studio для перагляду дадзеных.
- Kysely — это средства для стварэння запытак у час выканання. Вы пісвеце запыткі у формате SQL на TypeScript, кампайляр пераканалюе назвы табелей і столбцоў, а сама бібліятэка заступаецца малым розмерам.
- prisma-kysely — это з’ѐеднальны элемент: генератор Prisma, які стварае адзначэнні типоў Kysely безпасцерага з вашай схемы Prisma.
Prisma застаецца ў вашым процесе разработкі, тады калі Kysely ёсць едыным шаром базы дадзеных у запусканам коде. Аднойчыны: вы трапляецеся без API Prisma Client, які ведае пра адносы межу элементамі, такімі як вярнутыя рэзультаты з include і вярнутыя рэзультаты після багаторазовых змены, а таксама без можлівасці самостойнага стварэння з’еднанняў. Якщо вы яшчэ выбіраеце шар дадзеных, порэванае raw SQL, Prisma і Drizzle дапамагае у прымітным выборе.
Інсталяцыя пакетаў
Для роботы програмы патрэбны Kysely, дыалект і драйвер; гэта дае можлівасць інсталявацыі стаку на аднойчыне з Neon (тут пользуецца pnpm, але працуюць таксама npm і yarn):
pnpm add kysely kysely-neon @neondatabase/serverless
pnpm add -D prisma prisma-kysely
Запамятаце, што prisma і prisma-kysely ўжо ўтвараюць частку дэпэндэнсіяў для разработкі: яны толькі керуюць схемай і генеруюць код.
Апісанне схемы і генераванне типаў Kysely
Шыматлік — звычны Prisma, за выключэнням таго, што генераторам ёсць prisma-kysely (запіс у ./types), а не звычны кліентскі генератор. У ём узначаюцца User і Post з адно-дацяным адносункам.
// db/schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator kysely {
provider = "prisma-kysely"
output = "./types"
}
model User {
id Int @id @default(autoincrement())
name String
email String @unique
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
authorId Int
createdAt DateTime @default(now())
author User @relation(fields: [authorId], references: [id])
}
prisma generate тепер стварае типы Kysely замест кліента, а prisma db push застосоўвае шыматлік да базы дадзеных:
pnpm prisma generate
pnpm prisma db push
Рэзультатам ёсць файл на кшталт db/types/kysely.d.ts з інтерфейсам DB, які описвае кожную табліцу. Тры застерэжэння:
- Шыматлік знаходзіцца ў
db/schema.prisma, а не у стандартным для Prismaprisma/schema.prisma; таму неабходна націснуць CLI на яго (напрыклад, за дапамою--schema) па трэбаванню вашай версіі Prisma.
db push сінхронізуе базу дадзеных без запісву файлаў міграцый. Для даных у працоўнай сэрвісе prisma migrate dev і prisma migrate deploy ствараюць версіяваныя міграцыі, не зменяючы рэшту процесу работы.url не прыманяецца, пераканайцеся ў актуальных інструкцыях.Скрыпты пакетаў для ўседзённага цыклу
Калькі скрыптав расхляблююць процес работы для каманды:
{
"scripts": {
"db:push": "prisma db push",
"db:generate": "prisma generate",
"db:studio": "prisma studio"
}
}
З іх наявнасцю змена схемы выражаецца за дапамою двух каманд:
# To generate the types
pnpm db:generate
# To push to the remote DB
pnpm db:push
Тады база дадзеных і типы Kysely застаюцца сувязанымі, таму кампайляр пазначае будзь-які запыт, який выкарыстоўвае перайменаваны або адчынены столбец.
Выбір дыялекта Kysely
Kysely не спілкуецца безпосередна з самай базай дадзеных. Діялект знаходзится межу будоўнікам запытаў і драйверам і ведае, як скомпіляваць і адправляць запыты для адной базай дадзеных і аднаго спосабу з’яўлення. Афіцыйныя діялекты падтрымляюць PostgreSQL, MySQL і SQLite; діялекты спальноты — такія сервісы як Neon, PlanetScale і Turso. Для Postgres два варыянты падтрымліваюць большасць случаў.
Neon через HTTP для размешчэння без сервера
На Vercel або падобной платформе HTTP-драйвер Neon чырпаецца добра: кожны запыт ёсць безстановым запитам, таму не трэба падтрымваць стойкія з’яўленне межу короткімі вызывамі. Настройка загортае neon() у NeonDialect і прызначае Kysely з генераваным DB:
// db/index.ts
import { Kysely } from 'kysely'
import { NeonDialect } from 'kysely-neon'
import { neon } from '@neondatabase/serverless'
import type { DB } from './types/kysely'
const db = new Kysely<DB>({
dialect: new NeonDialect({
neon: neon(process.env.DATABASE_URL!),
}),
})
export default db
! толькі змушвае TypeScript мовчаць; ён нічаго не перакантролюе. Большыя обмежэнні — kysely-neon через HTTP не можа выконваць транзакцыі чыста запыты на адной сесыі, таму ён падходзіць для простых оперэйцыяў CRUD і сторанак, дзе больша частка — чытанне, а не робота з калькамі. З драйверам WebSocket Neon вам абоўсумова не патрэбны kysely-neon: прасуньте Pool Neon у вбудованы PostgresDialect Kysely. API kysely-neon таксама зменяўся між выданнямі, таму пораўнайце яго з актуальным README.
node-postgres для сервераў, якія працуюць дзёўга
Для сервера Node.js, які працуе дзёўга, офіцыйны драйвер pg — гэта найболей комплектны выбар, з транзакцыямі, пулінгам і падготавленымі запытамі. Ён падключаецца да власнага PostgresDialect Kysely:
// db/index.ts
import { Kysely, PostgresDialect } from 'kysely'
import { Pool } from 'pg'
import type { DB } from './types/kysely'
const db = new Kysely<DB>({
dialect: new PostgresDialect({
pool: new Pool({
connectionString: process.env.DATABASE_URL,
}),
}),
})
export default db
Выбір межы ямі
Разлік заключаецца у модэлі з’яўлення звязку. kysely-neon — это безстановы HTTP: лёгкі і падходзячы для сервероў без адпаведных рэшарактараў, але без падтрымкі транзакцый. pg падтрымвае відкрытыя TCP-з’язкі, а також усю сукупнасць функцый, што падходзіць для сервераў, які працуюць стала. Выкарыстоўваюце kysely-neon на платформах без адпаведных рэшарактараў, такіх як Vercel чы Netlify, а pg чы пул Neon WebSocket — калі вам патрэбныя транзакцыі. Будзьце ажырэйны пулам pg унутранік сервероў без адпаведных рэшарактараў: кожны экземпляр стварае своі з’язкі, і гэта можа выцягнуць максымальную кантэйнернасць базы дадзеных без зусібныя званоўкі званоўніка з’язкаў зза межаў.
Запытанні з серверскага компонента
Будзь-які код з боку сервера можа імпортуваць db. Шырыея серверскі компонент перыядычна показвае корыстувальнікаў, выбіраючы тры столбцы, аранжаваныя па id:
// app/users/page.tsx
import db from '@/db'
export default async function UsersPage() {
const users = await db
.selectFrom('user')
.select(['id', 'name', 'email'])
.orderBy('id')
.execute()
return (
<div>
<h1>Users</h1>
<ul>
{users.map(u => (
<li key={u.id}>{u.name} ({u.email})</li>
))}
</ul>
</div>
)
}
Паколькі DB выходзіць з схемы Prisma, неправильна напісанне табліцы або столбца спрычынае парабою пераказвання типаў, а users формуецца толькі з выбраных полей.
Є адна проблема: Prisma за замовчаннем называе табліцы на імена модэляў, таму гэтая схема стварае табліцу User, і генераваныя типы вжываюць гэтае імя. selectFrom('user') пераказвае типы толькі тады, калі да модэля дадаць @@map("user"); інакша запыт будзе до 'User'. Таксама не трэба включаць db у Кліентскія компаненты, адколькі ён чытае секрэтны данні, доступныя толькі на серверы.
Паўздневны процес работы
Калі все налаштавана, цикл выглядае так:
- Зменіце модэляў у
db/schema.prisma. - Паўтарна генеруйце типы і застосавіце змяны за дапамою двух скрыптав.
- Вжывайце
dbу Серверскіх компанентах, обробніках маршрутаў або Серверскіх дзеяннях.
Утварэны лейаут размешчае ўсё, што стосуецца базы дадзенаў, пад db/:
📦 my-next-app
├── 📁 app
│ └── 📁 users
│ └── page.tsx
├── 📁 db
│ ├── schema.prisma
│ ├── index.ts
│ └── 📁 types
│ └── kysely.d.ts
├── 📁 node_modules
├── .env
├── package.json
├── pnpm-lock.yaml
└── tsconfig.json
Заключэнне
Такое раздзелення дазволяе застаўляць робочы процес схемы Prisma і Studio без адправкі Prisma Client, а таксама дае вам невялікы шар запитоў у формате SQL, чыия типы стежаць за схемай.
- Застаўляйце
prismaіprisma-kyselyяк залежнасці для разработкі; толькі Kysely, дыялект і драйвер адправляюцца у працэс выканання. - Для простых безсерверных завадзяў выкорыстоўвайце дыялект Neon HTTP, а калі патрэбны транзакцыі — перайдзіце на
PostgresDialectз пулам. - Следзіце за называмі табэляў: генераваныя типы паходзяць з называў базы дадзенаў, якія за замовчаннем ўзімаюць назывы модэляў Prisma.
db push на правильныя міграцыі раней, чым данні ў базе дадзеных пачнуць мяць значэнне.