Topics

Verbinding maken met database met Supabase×Prisma (met Gemini CLI!)

  • column

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!

Auteur van dit artikel

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

Artikelen van deze medewerker bekijken

Ons sterke punt is ons betrouwbare teamstructuur en snelle responsiviteit

Bij Liberogic worden ervaren teamleden actief ingezet voor projectvoering, wat door klanten zeer wordt gewaardeerd.
We wijzen vakbekwaam projectmanagers en directors aan en streven ernaar projecten soepel te laten verlopen. We voorkomen onnodig kostenverhogingen door volledig inzet te vermijden en wijzen middelen toe waar ze het meest geschikt zijn. Onze snelheid bij taakanalyse en bij het opmaken en indienen van offertes is goed bekend.

* Wij voeren niet actief SES-achtige permanente werkzaamheden uit, dus graag van tevoren dank voor uw begrip.

U kunt vrijwel alle grote projectmanagementtools en chattoolsgebruiken, zoals Slack, Teams, Redmine, Backlog, Asana, Jira, Notion, Google Workspace, Zoom en Webex.

Bij grootschalige projecten met SES of offshoring: hebt u vragen of zorgen over technische uitdagingen en aanpak?

Casestudies