codelynx.dev
🇫🇷🇬🇧

Retour 09/02/2025

Guide complet de Prisma avec NextJS

Écris par Melvyn Malherbe le 09/02/2025


Je vais t'expliquer comment utiliser Prisma dans une application JavaScript en prenant notamment l'exemple de NextJS.

Ce guide va tout t'expliquer :

  1. Comment installer Prisma
  2. Comment fonctionne le système de migration de Prisma
  3. Comment utiliser Prisma dans ton application
  4. Usage avancé de Prisma
  5. Prisma avec TypeScript

Comment installer Prisma

Prisma vient avec deux librairies :

  1. prisma

C'est la librairie principale de Prisma qui va être installée dans les dépendances de dev. Elle permet principalement d'exécuter des commandes dans le terminal pour faire des actions.

  1. @prisma/client

C'est la librairie qui va être dans les dépendances et c'est elle qui va permettre de faire des requêtes à la base de données.

Pour installer Prisma, il y a une commande qu'on peut exécuter :

BASH
npx prisma init

Cette commande va installer les dépendances nécessaires et rajouter un dossier prisma dans ton projet avec un fichier schema.prisma.

      • schema.prisma
    • package.json

Ce fichier schema.prisma va nous permettre de définir les tables de notre base de données.

On va partir sur le principe que tu utilises PostgreSQL comme base de données, tu vas devoir modifier le fichier schema.prisma pour ajouter ta DATABASE_URL dans le fichier .env.

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

Et dans ton fichier .env, tu vas ajouter :

.env
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/postgres

Ensuite tu peux ajouter tes tables et relations. Voici l'exemple de la documentation :

schema.prisma
model Post {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  title     String   @db.VarChar(255)
  content   String?
  published Boolean  @default(false)
  author    User     @relation(fields: [authorId], references: [id])
  authorId  Int
}

model Profile {
  id     Int     @id @default(autoincrement())
  bio    String?
  user   User    @relation(fields: [userId], references: [id])
  userId Int     @unique
}

model User {
  id      Int      @id @default(autoincrement())
  email   String   @unique
  name    String?
  posts   Post[]
  profile Profile?
}

Ici tu peux voir qu'on a des relations, en installant l'extension VSCode Prisma tu verras qu'il t'aide super bien à créer des schémas cohérents.

Une fois qu'on a ajouté ça, on doit créer une migration.

Comment fonctionne le système de migration de Prisma

Le système de migration est un système populaire dans les bases de données qui permet de venir modifier la structure de ta base de données de manière évolutive.

C'est-à-dire que chaque fois qu'on va modifier le schéma, on va créer une migration, cette migration va venir modifier la base de données et potentiellement les données.

Ensuite quand on vient lancer la migration, celle-ci va appliquer chaque migration dans l'ordre, ce qui permet de faire des migrations sans risquer de perdre des données.

Pour créer une migration, on peut utiliser la commande suivante :

BASH
npx prisma migrate dev

Cette commande va créer une migration et l'appliquer à la base de données. Tu verras qu'il va te demander un nom pour la migration, tu peux simplement inscrire "init database" ou "initial migration".

Modification de la base de données

Imagine qu'on souhaite remplacer name par firstname et lastname dans notre schéma. Dans ce cas-là, on va modifier

schema.prisma
model User {
  id      Int      @id @default(autoincrement())
  email   String   @unique
  name    String?
  firstname String?
  lastname String?
  posts   Post[]
  profile Profile?
}

Dans ce cas-là c'est compliqué car on va perdre des données, car si on fait une migration qui supprime le champ name et rajoute firstname et lastname, on va perdre toutes les données de name.

Pour éviter ça, on va créer une nouvelle migration qui va venir ajouter les champs firstname et lastname et les remplir avec les données de name.

BASH
npx prisma migrate --create-only --name add-firstname-lastname

Cette commande va créer un fichier de migration dans ton projet, tu peux le voir dans le dossier prisma/migrations.

Ensuite on va pouvoir faire du SQL :

  1. Ajouter les champs firstname et lastname
  2. Remplir le champ firstname par le champ name
  3. Supprimer le champ name

Voici le code SQL :

SQL
ALTER TABLE "User" ADD COLUMN "firstname" text;
ALTER TABLE "User" ADD COLUMN "lastname" text;
UPDATE "User" SET "firstname" = "name";
ALTER TABLE "User" DROP COLUMN "name";

Et de cette manière, quand on va déployer notre site sur notre database de production, la migration va se faire et on va éviter de perdre des données.

Cette migration va ensuite s'effectuer chaque fois qu'on va lancer les migrations sur une "nouvelle base de données".

Les migrations viennent générer le @prisma/client

Le @prisma/client est généré en fonction de ton schéma. C'est-à-dire que tous les types sont générés chaque fois que tu fais une migration. Tu peux aussi générer les types avec la commande suivante :

BASH
npx prisma generate

Cette commande va venir générer le @prisma/client et les types dans le dossier node_modules.

C'est comme ça qu'ensuite tu vas pouvoir faire des requêtes à la base de données de manière "type-safe".

Comment utiliser Prisma dans ton application

Pour ajouter Prisma, on va utiliser un Singleton expliqué dans la documentation.

Dans un fichier lib/prisma.ts on va instancier notre Prisma :

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

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

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

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

Ce code permet d'éviter d'instancier plusieurs fois le PrismaClient dans ton application. Notamment quand tu publies l'application sur Vercel en "Serverless".

Une fois fait, tu peux utiliser prisma à n'importe quel endroit backend de ton application, comme un API Routes qui viendrait retourner tous les posts dans app/api/posts/route.ts :

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

export async function GET(request: Request) {
  const posts = await prisma.post.findMany(); 
  return NextResponse.json(posts); 
}

Ce code vient récupérer tous les posts disponibles et vient les retourner en format JSON. Tu peux le voir ici, mais avec Prisma tout est type-safe c'est-à-dire que quand tu écris prisma. tu as une auto-complétion automatique sur VSCode qui te propose post.

Usage avancé de Prisma

Tu peux utiliser Prisma pour faire à peu près tout ce qui est possible de faire avec SQL sauf si tu vas dans des cas trop compliqués. Mais voici des exemples typiques.

Récupérer tous les posts qui commencent par "Pourquoi"

TS
const posts = await prisma.post.findMany({
  where: {
    title: {
      startsWith: "Pourquoi"
    }
  }
})
  • where permet de filtrer les données
  • il existe ensuite plein de filtres built-in

Récupérer l'user avec l'id 1 et tous ses posts

TS
const user = await prisma.user.findUnique({
  where: {
    id: 1
  },
  include: {
    posts: true
  }
})

const posts = user.posts;
  • include vient inclure des relations à la valeur de retour

Récupérer l'user le nom et le titre de tous les posts de l'utilisateur avec l'id 1

TS
const posts = await prisma.post.findMany({
  where: {
    authorId: 1
  },
  select: {
    title: true,
    author: {
      select: { name: true }
    }
  }
})
  • select permet de sélectionner et récupérer uniquement les champs dont tu as besoin. Tu peux aussi sélectionner des données dans les relations.

Récupérer le nombre de posts de l'utilisateur avec l'id 1

TS
const posts = await prisma.post.count({
  where: {
    authorId: 1
  }
})
  • count permet de récupérer le nombre de données

Récupérer les 10 derniers posts

TS
const posts = await prisma.post.findMany({
  take: 10,
  orderBy: {
    createdAt: "desc"
  }
})
  • take permet de récupérer un nombre de données
  • orderBy permet de trier les données

Point sur les usages avancés

Il existe évidemment plein d'autres usages et de choses à faire. Je t'invite à utiliser ChatGPT si tu as des questions, il répond vraiment bien. Tu peux aussi lire la documentation.

Prisma avec TypeScript

Un truc que j'aime vraiment faire avec Prisma, c'est de générer des types TypeScript en fonction des query que je fais. Souvent dans mes applications je crée des méthodes pour séparer mes query de mes API Routes par exemple. Par exemple, je vais récupérer le user et ses posts dans une méthode :

TS
export const getUserWithPosts = async (userId: number) => {
  const user = await prisma.user.findUnique({
    where: { id: userId },
    select: {
      id: true,
      name: true,
      posts: {
        select: { 
          id: true, 
          title: true 
        }
      }
    }
  });
  return user;
}

Et ensuite souvent j'ai envie d'avoir un type qui correspond à cet objet. Pour ça, Prisma a prévu le coup et tu peux faire ceci.

TS
import { Prisma } from "@prisma/client";

type UserWithPosts = Prisma.PromiseReturnType<typeof getUserWithPosts>
// UserWithPosts = {
//   id: number;
//   name: string;
//   posts: { id: number; title: string }[];
// }

Et là, tu as un type qui correspond à l'objet que tu retournes dans ta fonction.

Tu peux donc créer un Server Component qui va prendre en props ce fameux user avec le bon type :

TSX
export const UserWithPostsCard = ({ user }: { user: UserWithPosts }) => {
  return (
    <div>
      <h1>{user.name}</h1>
      {user.posts.map((post) => (
        <div key={post.id}>{post.title}</div>
      ))}
    </div>
  )
}

Et là, tu as une auto-complétion sur VSCode qui te propose les champs de l'objet.

L'avantage de dingue ici c'est que si tu viens modifier les données que tu récupères dans la méthode getUserWithPosts tu vas avoir TypeScript qui va automatiquement modifier le type et t'afficher ou non des erreurs en fonction. J'utilise ça tout le temps et c'est vraiment très puissant.

Conclusion

Dans ce guide je t'ai présenté les points les plus importants de Prisma ! J'ai une formation "NextReact" qui contient un module entier sur Prisma et tu peux tester ma formation gratuitement ici :

Le meilleur moyen d'apprendre NextJS !

Rejoins par développeurs, cette formation reçoit une note de 4.7 / 5 🚀

Reçois la formation gratuitement dans ta boîte mail :

NextReact

Cours NextJS gratuit

Accède à des exercices, des vidéos et bien plus sur NextJS dans la formation "NextReact" 👇