Shō et Hassie, entre autres, sont en train de réaliser des projets de développement intéressants en utilisant Supabase. Contrairement au développement en cascade traditionnel, on entend parler de définition des exigences fonctionnelles à partir de l'UI, et je ne veux pas être en reste !
Cet article présente, sous forme de mémo, les étapes pour créer une application de notes simple et enregistrer des données dans une base de données en connectant Supabase et Prisma. Gemini CLI sera également utilisé, bien sûr !
Environnement : Next.js
Comme nous n'utilisons pas l'authentification, le temps réel ni RLS de Supabase, mais uniquement ses fonctionnalités de base de données via l'API, nous avons choisi Prisma. Il permet de manipuler les tables de la base comme des objets JavaScript / TypeScript, ce qui permet une écriture familière pour les ingénieurs frontend.
Prisma
Prisma ORM est une bibliothèque ORM (Object-Relational Mapping) utilisable avec TypeScript et JavaScript.
En résumé, il s'agit d'un outil qui permet d'effectuer des opérations sur la base de données à l'aide de méthodes définies dans le langage de programmation, sans écrire de SQL.
De plus, Prisma génère automatiquement des types à partir du schéma de la base de données. Ainsi, si vous tentez de manipuler une colonne inexistante ou des données de type incorrect, une erreur de compilation vous alerte immédiatement !
Supabase
Supabase est un service backend full-stack qui gagne en popularité comme alternative open source à Firebase.
- Une grande évolutivité et une fiabilité élevée, reposant sur une base de données PostgreSQL
- Notification automatique des modifications de données grâce à la fonctionnalité de base de données en temps réel
- Prise en charge de multiples méthodes d'authentification (e-mail/mot de passe, connexion via réseaux sociaux, authentification par téléphone, etc.)
- Gestion efficace des fichiers volumineux grâce à la fonctionnalité de stockage de fichiers
- Développement rapide grâce à la génération automatique d'API RESTful et d'API GraphQL
- Large choix d'outils et de SDK pour les développeurs, configuration et mise en place simples
Comme nous accordons une grande importance à la procédure d'intégration avec Supabase, nous confierons la création de l'interface à Gemini CLI. Un outil étonnamment pratique, à tel point que c'en est presque émouvant ! Heureusement que notre entreprise utilise Google Workspace !
Je souhaite créer une fonctionnalité de notes avec Supabase et Prisma. Pour commencer, pouvez-vous créer un fichier page.tsx ?
D'accord, dans ce cas, pourriez-vous faire en sorte que le contenu saisi dans le textarea soit ajouté sous forme de liste dans Your Memos lorsque le bouton Save Memo est cliqué ?
L'aspect visuel est correct ! Le contenu saisi est désormais ajouté à la liste ci-dessous. Cependant, comme cela repose uniquement sur un événement JavaScript, la liste disparaît lors d'un rechargement de la page.
Pour conserver le contenu saisi, on utilise une base de données !
Commençons par créer un nouveau projet dans Supabase.
Créez le projet à l'aide du bouton « New Project ». Notez le Database password, car il sera nécessaire pour la connexion à Prisma.
Ensuite, connectons Prisma.
npm install prisma --save-dev
npx prisma init
Une fois ces commandes saisies, Prisma est installé et le dossier prisma apparaît.
Dans le fichier .env, remplacez la valeur de DATABASE_URL par l'URL de connexion de Supabase. Dans la partie [YOUR-PASSWORD], indiquez le Database password défini précédemment dans Supabase.
DATABASE_URL="postgresql://postgres.odoaingwnxkhkeujwhtp:[YOUR-PASSWORD]@aws-1-ap-northeast-1.pooler.supabase.com:5432/postgres"
Rédigez ensuite le schéma (la définition de la structure de la base de données) dans /prisma/schema.prisma.
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Memo {
id Int @id @default(autoincrement())
content String
createdAt DateTime @default(now())
}
model ○○ peut être nommé librement.
Une fois le schéma rédigé, lancez la migration.
npx prisma migrate dev --name init
Un fichier migration.sql est généré et les tables de données sont créées côté Supabase.
Création d'une API pour se connecter à Supabase
Nous créons une API de connexion pour enregistrer les valeurs saisies dans Supabase.
Installation de Prisma Client dans le projet.
npm install @prisma/client
Connexion à Supabase
/libs/prisma.ts
import { PrismaClient } from "@prisma/client";
const Prisma = new PrismaClient(); //インスタンス化
export const main = async () => {
try {
await Prisma.$connect();
} catch (error) {
return Error("DB接続に失敗しました");
}
};
API
/api/memos/route.ts
import { NextResponse } from "next/server";
import { prisma } from '@/lib/prisma';
export const GET = async (req: Request, res: NextResponse) => {
try {
await main();
const memos = await Prisma.memo.findMany();
return NextResponse.json(memos);
} catch (error) {
return NextResponse.json("エラーが発生しました");
} finally {
await Prisma.$disconnect();
}
};
export const POST = async (req: Request, res: NextResponse) => {
const { content } = await req.json();
try {
await main();
const memos = await Prisma.memo.**create**({
data: {
content: content,
},
});
return NextResponse.json(memos);
} catch (error) {
return NextResponse.json("エラーが発生しました");
} finally {
await Prisma.$disconnect();
}
};
La fonction GET est une API qui récupère l'ensemble des enregistrements de la base de données. La méthode findMany() permet de récupérer tous les enregistrements correspondant à la condition. Dans Prisma.memo.findMany(), « memo » correspond au nom du schéma.
La fonction POST est une API qui ajoute des données à la base de données. Elle s'appuie sur create() pour créer les enregistrements.
D'autres méthodes, comme la suppression ou la mise à jour, sont également disponibles. Vous pouvez les utiliser dans un style proche de JavaScript, sans avoir à écrire de requêtes SQL.
La préparation de base est maintenant terminée.
Il ne reste plus qu'à reprendre l'API écrite précédemment dans page.tsx et à l'intégrer.
'use client';
import React, { useState, useEffect } from 'react';
interface Memo {
id: number;
content: string;
createdAt: string;
}
export default function MemoApp() {
const [memos, setMemos] = useState<Memo[]>([]);
const [newMemo, setNewMemo] = useState('');
const fetchMemos = async () => {
const response = await fetch('/api/memos');
const data = await response.json();
setMemos(data);
};
useEffect(() => {
fetchMemos();
}, []);
const handleSaveMemo = async (e: React.FormEvent) => {
e.preventDefault();
if (newMemo.trim() !== '') {
await fetch('/api/memos', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ content: newMemo }),
});
setNewMemo('');
fetchMemos();
}
};
return (
<div className="bg-white min-h-screen">
<div className="max-w-2xl mx-auto px-4 py-16">
<header className="text-center mb-12">
<h1 className="text-5xl font-extrabold text-gray-900">Memo</h1>
</header>
<main>
<div className="mb-12">
<form onSubmit={handleSaveMemo}>
<textarea
className="w-full p-4 text-gray-800 bg-gray-100 rounded-lg border-2 border-gray-200 focus:outline-none focus:ring-2 focus:ring-gray-400 focus:border-transparent transition"
placeholder="Create a new memo..."
rows={3}
value={newMemo}
onChange={(e) => setNewMemo(e.target.value)}
></textarea>
<div className="flex justify-end mt-4">
<button
type="submit"
className="px-6 py-2 bg-gray-800 text-white font-semibold rounded-lg hover:bg-gray-900 transition"
>
Save Memo
</button>
</div>
</form>
</div>
<section>
<h2 className="text-3xl font-bold text-gray-800 mb-6">Your Memos</h2>
<div className="space-y-4">
{memos.length > 0 ? (
memos.map((memo) => (
<div key={memo.id} className="bg-gray-50 p-6 rounded-lg shadow-sm">
<p className="text-gray-700">{memo.content}</p>
</div>
))
) : (
<div className="text-center text-gray-500">
<p>No memos yet. Add one above!</p>
</div>
)}
</div>
</section>
</main>
</div>
</div>
);
}
Elles sont bien enregistrées côté Supabase !
Cette fois, je me suis appuyé sur Gemini pour créer l'application dans les grandes lignes, mais en utilisant une base de données pour enregistrer les valeurs, on peut aussi élargir les fonctionnalités et les applications que l'on peut créer !
Je pensais que le backend serait compliqué… mais grâce à l'outil GUI pour gérer la base de données, c'est très clair, et le seuil d'entrée pour connecter une base de données s'est nettement abaissé !
Génial !
Je travaille sur le développement frontend, principalement en balisage, avec JavaScript, React et Next.js. Je suis ravi lorsque les sites auxquels j'ai contribué sont mis en ligne avec succès ! Passionné de guitare, j'aime aussi les chats et les patates douces grillées 🐱🍠
Hiratchi
Ingénieur frontend / Entré en 2022