Галоўная / Артыкулы

Next.js Server Actions з Prisma і PostgreSQL

Next.js Server Actions каналізуецца яшчэ безпосерэднія з’еднанне з аднальным кліентам Prisma і базайнам дадзеных PostgreSQL, таму задачы тыпу CRUD працуюць без неабяжных API-маршрутаў і запытоў fetch з боку кліента.

Выдавец: REACTAPP.TOP4 хв чытання917 слоў

Крыніцы: Next.js Server Actions + Prisma + PostgreSQL: The Integration Pattern You Actually Need

У нарадчыках частаюць падробныя адгукіі пра Next.js, Prisma і PostgreSQL як абсалютна самастоятэльная сістэмы: ствараецца каркас прыложэння, генеруецца кліентскі кантакт, настаўляецца звязок з базай дадзеных, выкананыя міграцыі. Недастатак — гэта як гэтыя тры слоі з’едынаюцца ў адну модэль інтэграцыі, і чаму гэтая модэль пазбавляе нас вельмі большай часткі звычных процэдурах для цэлага стака.

Разпад працы ўсё чытра. Server Actions пераводзяць задачы за межы сервера. Prisma выдае запіты з абавесцю тыпаў. PostgreSQL храніць рэкі. Кожны слой адпавядае за сваю задачу. Разам яны пазбавляюць нас цэлага сяроднего слоя: ні спецыяльных маршрутаў API, ні ручна напісаных цыклів fetch, ні дадатковых процэсаў серыялізацыі межу компанентам React і базай дадзеных.

Дастатнька простая адміністрацыя задач, каб паказаць всю модэль ад самага схематызавання да рабочай інтэрфейсу, без неабходнасці стварання спецыяльных працоўнікаў маршрутаў для оперэйцыяў CRUD.

Чаму саме гэты стак

Дзеянні сервера, Prisma і PostgreSQL адказваюць адзіны другаму на кожным слою заўсёдышнага прыкладу Next.js.

Дзеянні выкананы на серверэ, таму ў яных можна безпасабліва імпортаваць кліента Prisma, не выкладваючы пароліў да базы дадзеных у браузер. Prisma забезпечвае тыпаваную плошчу для запытоў, таму значэнні, якія заносяцца ў PostgreSQL і якія чытуюцца звярнуў, застаюць супараднае ў всім графе TypeScript. PostgreSQL яўляецца надзеяным, шырока падтрымваным рашэнням і чыста работае з працэсам міграцый Prisma.

Рэзультатам яе вікорыстоўвання ёсць короткі шлях ад нажатыя на кнопку да стварэння і зберагання рэкорда — зазвычай з меншым колькам коду, чым у іншых падходах у экасістэме Next.js.

Настройка праекта

Пачніце з новага прыкладу Next.js і дадзіце Prisma:

npx create-next-app@latest my-app --typescript
cd my-app
npm install prisma @prisma/client
npx prisma init

The prisma init command creates a prisma/ folder with a schema.prisma file and a .env file. Open .env and add your PostgreSQL connection string:
```DATABASE_URL="postgresql://USER:PASSWORD@HOST:5432/mydb"

3. Define Your Schema

Open prisma/schema.prisma and define your data model. We will keep it simple — a Task model:
```generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model Task {
  id        String   @id @default(cuid())
  title     String
  completed Boolean  @default(false)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

Run the migration to create the table:
```npx prisma migrate dev --name init

This creates the table and generates the Prisma Client. You are ready to query.

Шаблон інтэграцыі

Гэта ўсходнія ідэя. Server Action імпортуе кліента Prisma і ведае справы безпасульна з самай базой дадзеных — няма API-маршрута, няма кліентскага fetch, і няма дапаможнага шара серыявання межу інтэрфейсам і базай дадзеных. Спачатку экспортуеяце спакульную інстанцыю Prisma, якая застаецца пасля гарачага перзапуску пад разработке:

// lib/prisma.ts
import { PrismaClient } from '@prisma/client';

const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };

export const prisma =
  globalForPrisma.prisma ?? new PrismaClient();

if (process.env.NODE_ENV !== 'production')
  globalForPrisma.prisma = prisma;

Потым задаеце модуль Server Actions:

// app/tasks/actions.ts
'use server';
import { revalidatePath } from 'next/cache';
import { prisma } from '@/lib/prisma';

export async function getTasks() {
  return prisma.task.findMany({ orderBy: { createdAt: 'desc' } });
}
5. Wiring It to Your UI

Now use the Server Actions in your page and components:
```// app/tasks/page.tsx
import { getTasks } from './actions';
import { TaskForm } from './TaskForm';
import { TaskList } from './TaskList';

export default async function TasksPage() {
  const tasks = await getTasks();
  return (
    <main>
      <h1>My Tasks</h1>
      <TaskForm />
      <TaskList tasks={tasks} />
    </main>
  );
}
export async function createTask(formData: FormData) {
  const title = formData.get('title') as string;
  if (!title?.trim()) return { error: 'Title is required' };
  await prisma.task.create({ data: { title } });
  revalidatePath('/tasks');
}

export async function toggleTask(id: string, completed: boolean) {
  await prisma.task.update({ where: { id }, data: { completed: !completed } });
  revalidatePath('/tasks');
}

export async function deleteTask(id: string) {
  await prisma.task.delete({ where: { id } });
  revalidatePath('/tasks');
}

Інтэграцыя з інтэрфейсам

Выклікаеце гэтыя дзеяння з старонкі. Компанента сервера можа безпасульна вызваць getTasks() — няма useEffect, няма ручнага флажка загрузкі, і няма кліентскага fetch:

// app/tasks/page.tsx
import { getTasks } from './actions';
import { TaskForm } from './TaskForm';
import { TaskList } from './TaskList';

export default async function TasksPage() {
  const tasks = await getTasks();
  return (
    <main>
      <h1>My Tasks</h1>
      <TaskForm />
      <TaskList tasks={tasks} />
    </main>
  );
}

Заключэнне

Server Actions па Prisma па PostgreSQL даюць вам цэласпрамованы шлях для обработкі дадзеных парадоксальна меры без зайвага коду. Компонент вызывае функцыю, якая пасля чаго запішвае або чытае дадзеныя праз Prisma, PostgreSQL храніць гэтыя дадзеныя, а revalidatePath апдэйтуе інтэрфейс — зазвычай у калькі дзесяткаў ліній коду, а не праз околачыцую шар API.