MyApp

Getting Started

IntroductionInstallationPull Updates
Architecture

Setup

IDEAI AgentsMCP ServersEnvironment Variables

Workflow

Git WorkflowBuild & DeployTroubleshooting

Authentication

OverviewSetup & ConfigurationUsage & IntegrationTroubleshooting

Payments

OverviewSetup & ConfigurationUsage & IntegrationTroubleshooting

Supabase

OverviewSetup & ConfigurationTroubleshooting

Database

Database SetupPrisma ORMUsage & IntegrationMigrationsTroubleshooting

Storage

OverviewSetup & ConfigurationUsage & IntegrationTroubleshooting

Emails

OverviewSetup and ConfigurationUsage and IntegrationTroubleshooting

SEO

OverviewConfiguration & Best PracticesCustomization & Optimization

UI

OverviewSetup and ConfigurationThemingTroubleshooting
MyApp

Usage & Integration

Learn how to use Prisma Client in your Plainform application.

This page shows practical examples of using Prisma Client in Plainform for database queries and mutations.

Prisma Client Setup

Plainform uses a singleton pattern to prevent connection exhaustion:

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

declare global {
  var prisma: PrismaClient | undefined;
}

let prisma: PrismaClient;

if (process.env.NODE_ENV === 'production') {
  prisma = new PrismaClient();
} else {
  if (!global.prisma) {
    global.prisma = new PrismaClient();
  }
  prisma = global.prisma;
}

export { prisma };

Why singleton? Prevents multiple Prisma instances in development and avoids connection pool exhaustion.

Basic CRUD Operations

Create and Read

app/api/events/route.ts
import { prisma } from '@/lib/prisma/prisma';
import { NextResponse } from 'next/server';

export async function POST(req: Request) {
  const { text, type, slug, timestamp } = await req.json();

  const event = await prisma.event.create({
    data: { text, type, slug, timestamp: BigInt(timestamp) }
  });

  return NextResponse.json({ event });
}

export async function GET() {
  // Find single record
  const event = await prisma.event.findFirst({
    orderBy: { timestamp: 'desc' }
  });

  // Find many records
  const events = await prisma.event.findMany({
    where: { type: 'post' },
    orderBy: { timestamp: 'desc' },
    take: 10
  });

  return NextResponse.json({ event, events });
}

Update and Delete

app/api/events/route.ts
export async function PATCH(req: Request) {
  const { id, text } = await req.json();

  const event = await prisma.event.update({
    where: { id },
    data: { text }
  });

  return NextResponse.json({ event });
}

export async function DELETE(req: Request) {
  const { searchParams } = new URL(req.url);
  const type = searchParams.get('type');

  await prisma.event.deleteMany({ where: { type } });

  return NextResponse.json({ message: 'Deleted' });
}

Filtering and Pagination

Example queries
// Where clauses
const posts = await prisma.event.findMany({
  where: {
    type: 'post',
    timestamp: { gte: BigInt(Date.now() - 86400000) }
  }
});

// OR conditions
const events = await prisma.event.findMany({
  where: {
    OR: [{ type: 'post' }, { type: 'update' }]
  }
});

// Pagination
const page = 1;
const limit = 20;

const events = await prisma.event.findMany({
  skip: (page - 1) * limit,
  take: limit,
  orderBy: { timestamp: 'desc' }
});

Relationships

Including related data
// Assuming Post and Comment models
const posts = await prisma.post.findMany({
  include: {
    author: true,
    comments: {
      take: 5,
      orderBy: { createdAt: 'desc' }
    }
  }
});

// Create with relationships
const post = await prisma.post.create({
  data: {
    title: 'My Post',
    author: { connect: { id: userId } },
    comments: {
      create: [{ text: 'First comment', authorId: userId }]
    }
  },
  include: { comments: true }
});

Server Components

Use Prisma directly in Server Components:

app/dashboard/page.tsx
import { prisma } from '@/lib/prisma/prisma';

export default async function DashboardPage() {
  const events = await prisma.event.findMany({
    orderBy: { timestamp: 'desc' },
    take: 10
  });

  return (
    <div>
      <h1>Recent Events</h1>
      {events.map(event => (
        <div key={event.id}>{event.text}</div>
      ))}
    </div>
  );
}

Server Components can query the database directly without API routes, reducing latency.

Transactions

Use transactions for operations that must succeed or fail together:

Example transaction
const result = await prisma.$transaction([
  prisma.event.deleteMany({ where: { type: 'old' } }),
  prisma.event.create({
    data: { type: 'new', text: 'New event', slug: 'new', timestamp: BigInt(Date.now()) }
  })
]);

BigInt Serialization

PostgreSQL BIGINT fields require special handling for JSON:

lib/utils.ts
export function serializeBigInt(obj: any): any {
  return JSON.parse(
    JSON.stringify(obj, (key, value) =>
      typeof value === 'bigint' ? value.toString() : value
    )
  );
}
app/api/events/route.ts
import { serializeBigInt } from '@/lib/utils';

export async function GET() {
  const event = await prisma.event.findFirst();
  return NextResponse.json({ event: serializeBigInt(event) });
}

Why needed? JavaScript's JSON.stringify() can't serialize BigInt and throws an error.

Error Handling

Handle Prisma errors gracefully:

app/api/events/route.ts
import { Prisma } from '@prisma/client';

export async function POST(req: Request) {
  try {
    const data = await req.json();
    const event = await prisma.event.create({ data });
    return NextResponse.json({ event });
  } catch (error) {
    if (error instanceof Prisma.PrismaClientKnownRequestError) {
      if (error.code === 'P2002') {
        return NextResponse.json(
          { error: 'Record already exists' },
          { status: 409 }
        );
      }
    }
    
    return NextResponse.json(
      { error: 'Database operation failed' },
      { status: 500 }
    );
  }
}

Next Steps

  • Migrations - Manage schema changes
  • Troubleshooting - Resolve common issues
  • Prisma Client API - Complete reference

How is this guide ?

Last updated on

Prisma ORM

Learn how to define database models and generate the Prisma Client.

Migrations

Manage database schema changes with Prisma Migrate.

On this page

Prisma Client Setup
Basic CRUD Operations
Create and Read
Update and Delete
Filtering and Pagination
Relationships
Server Components
Transactions
BigInt Serialization
Error Handling
Next Steps