Shō en Hasshi werken met Supabase en doen interessante dingen. Anders dan traditionele watervalmodellen horen we verhalen over het definiëren van functionaliteitsvereisten vanuit de UI, maar ik kan niet achterblijven!
Deze keer maak ik een eenvoudige notitie-app en leg ik vast hoe je Supabase en Prisma integreert om gegevens in de database op te slaan. We gebruiken ook Gemini CLI!
Omgeving: Next.js
We gebruiken niet de Auth-, Realtime- en RLS-functies van Supabase, maar Prisma om databasefunctionaliteit via API te gebruiken. Omdat je databasetabellen kunt behandelen als JavaScript/TypeScript-objecten, kun je code schrijven die vertrouwd is voor frontendengineers.
Prisma
Prisma ORM is een ORM-bibliotheek (Object-Relational Mapping) die beschikbaar is voor TypeScript en JavaScript.
Simpel gezegd: het is een tool waarmee je databasebewerkingen kunt uitvoeren zonder SQL te schrijven, met behulp van methoden die zijn gedefinieerd als objecten in je programmeertaal.
Bovendien genereert Prisma automatisch typen op basis van je databaseschema. Als je probeert kolommen te gebruiken die niet bestaan of gegevens van het verkeerde type te manipuleren, zul je dat ontdekken door een compilatiefout!
Supabase
Supabase is een volledig backend-service dat als open-source Firebase-alternatief sterk aan populariteit wint.
- Hoge uitbreidbaarheid en betrouwbaarheid op basis van PostgreSQL-database
- Automatische meldingen van gegevenswijzigingen dankzij real-time databasefunctionaliteit
- Ondersteuning van diverse authenticatiemethoden (e-mail/wachtwoord, sociale login, telefoonauthenticatie, enzovoort)
- Efficiënt beheer van grote bestanden met bestandsopslagfunctionaliteit
- Snelle ontwikkeling dankzij automatische generatie van RESTful API en GraphQL API
- Veel gereedschappen en SDK's voor ontwikkelaars, eenvoudige configuratie en implementatie
Omdat ik de integratieStappen met Supabase belangrijk vind, laat ik Gemini CLI de UI-onderdelen voor me genereren. Dit ding is ongelooflijk handig! Het was een geluk dat ons bedrijf Google Workspace gebruikt!
Ik wil een notitiesfunctie maken met Supabase en Prisma. Kun je alsjeblieft eerst page.tsx aanmaken?
Prima, dan zal ik het zo inrichten dat de inhoud die je in de textarea invoert wordt toegevoegd aan 'Your Memos' als een lijstitem wanneer je op de 'Save Memo'-knop klikt.
Het uiterlijk ziet er zo uit, prima! De ingevoerde inhoud wordt nu aan de onderstaande lijst toegevoegd. Dit gebeurt echter alleen met JavaScript-evenementen, dus wanneer je de pagina herlaadt, verdwijnt de lijst.
Om de ingevoerde inhoud te behouden, gebruiken we een database!
Eerst maken we een nieuw project aan op Supabase.
Maak het project aan via de knop 'New Project'. Onthoud het databasewachtwoord goed, want je hebt het nodig wanneer je Prisma verbindt.
Vervolgens verbinden we Prisma.
npm install prisma --save-dev
npx prisma init
Wanneer je deze commando's invoert, wordt Prisma geïnstalleerd en verschijnt de prismamap.
Vervang DATABASE_URL in het .env-bestand met de verbindingURL van Supabase. Vervang [YOUR-PASSWORD] met het databasewachtwoord dat je eerder in Supabase hebt ingesteld.
DATABASE_URL="postgresql://postgres.odoaingwnxkhkeujwhtp:[YOUR-PASSWORD]@aws-1-ap-northeast-1.pooler.supabase.com:5432/postgres"
Vervolgens schrijf je het schema (de structuurdefinitie van de database) in /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 ○○ kan naar wens worden benoemd.
Nadat je het schema hebt geschreven, voer je een migratie uit.
npx prisma migrate dev --name init
Het bestand migration.sql wordt gegenereerd en er wordt een gegevenstabel aangemaakt aan de kant van Supabase.
API maken voor verbinding met Supabase
We maken een API voor verbinding om de ingevoerde waarden op te slaan in Supabase.
Installeer Prisma Client in het project.
npm install @prisma/client
Verbinding met 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();
}
};
De GET-functie is een API die alle records uit de database ophaalt en met de methode findMany() worden alle records opgehaald die aan de voorwaarden voldoen. 'memo' in Prisma.memo.findMany() is de schemanaam.
De POST-functie is een API die gegevens toevoegt aan de database en maakt deze aan met create().
Er zijn ook andere methoden voor verwijdering en updates beschikbaar, en je kunt deze gebruiken met JavaScript-logica zonder SQL-statements te hoeven schrijven.
Hiermee is de voorbereiding compleet.
Daarna hoef je alleen de eerder geschreven API naar page.tsx te halen en in te voegen.
'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>
);
}
Dit wordt opgeslagen in Supabase!
Deze keer heb ik me op Gemini verlaten om het ruwweg in elkaar te zetten, maar als we een database gebruiken om waarden op te slaan, kunnen we veel meer functies en apps creëren!
Ik had het vooroordeel dat backend ingewikkeld zou zijn, maar met GUI-hulpmiddelen kun je gemakkelijk databases beheren en is de drempel voor databaseintegratie veel lager!
Ja!
Ik concentreer me op markup en ontwikkel frontends met JavaScript, React en Next.js. Het geeft me veel voldoening als een website waaraan ik heb gewerkt succesvol wordt gepubliceerd! Mijn hobby's zijn gitaar spelen. Ik ben dol op katten en zoete aardappelen🐱🍠
Hiracchi
Frontend-engineer / aangenomen in 2022