切換顯示語言

Topics

使用 Supabase 和 Prisma 連接到資料庫(使用 Gemini CLI!)

  • column

Kakeru先生、Hasshi先生和其他人正在使用Supabase進行一些有趣的開發。與我們迄今為止所看到的瀑布式開發不同,我聽到了各種關於從UI定義功能需求的說法,但我無法讓自己被超越!

因此,這次我將創建一個簡單的備忘錄應用程序,並總結連接 Supabase 和 Prisma 並將資料作為備忘錄保存在資料庫中的步驟。Gemini CLI我也要用!

環境:Next.js

我們不會使用 Supabase 的 Auth、Realtime 或 RLS,而是使用 Prisima 透過 API 存取資料庫功能。由於資料庫表可以像 Javascript/Typescript 物件一樣處理,我們認為前端工程師可以輕鬆編寫他們熟悉的程式碼。

Prisma

Prisma ORM 是一個可與 TypeScript 和 JavaScript 一起使用的 ORM(物件關聯映射)函式庫。

簡單來說,它是一種讓你不用寫SQL,而是使用程式語言的物件中定義的方法,來操作資料庫的工具。

此外,Prisma 會自動從資料庫模式產生類型,因此如果您嘗試操作資料庫中不存在的列或錯誤類型的數據,您將收到編譯錯誤通知!

Supabase

Supabase 是一種全端後端服務,作為開源 Firebase 的替代品,其吸引力越來越大。

  • 基於 PostgreSQL 資料庫,具有高度可擴展性和可靠性
  • 即時資料庫功能會自動通知您資料變化
  • 支援多種身份驗證方法(電子郵件/密碼、社交登入、電話身份驗證等)
  • 文件儲存功能,高效率管理大文件
  • 透過自動產生 RESTful 和 GraphQL API 實現快速開發
  • 豐富的開發工具和 SDK 讓設定和部署變得簡單

我想強調一下連接到 Supabase 的步驟,Gemini CLI這是一款超方便的產品,簡直讓人想哭!我公司用的是 Google Workspace,太開心了!

我想使用 Supabase 和 Prisma 建立一個備忘錄功能。首先,建立 page.tsx。

好的,那麼,我想進行設置,以便當我按下「儲存備忘錄」按鈕時,我在文字區域中輸入的內容將會新增到「您的備忘錄」清單中。

看起來就像這樣,一切正常!您輸入的內容現在將會加入到下面的清單中。但是,由於這只是一個 JavaScript 事件,因此如果您重新加載,列表將會消失。

我們使用資料庫來儲存您的輸入!

首先,在Supabase端建立一個新專案。

使用“新建專案”按鈕建立一個新專案。請記下資料庫密碼,因為連接 Prisma 時需要用到它。

接下來,連接 Prisma。

npm install prisma --save-dev

npx prisma init

輸入這些命令將安裝 Prisma 並建立 Prisma 資料夾。

將 .env 檔案中的 DATABASE_URL 替換為 Supabase 連線 URL。將 [YOUR-PASSWORD] 替換為您在 Supabase 中設定的資料庫密碼。

DATABASE_URL="postgresql://postgres.odoaingwnxkhkeujwhtp:[YOUR-PASSWORD]@aws-1-ap-northeast-1.pooler.supabase.com:5432/postgres"

然後/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())
}

○○型號可以隨意命名。

一旦編寫了模式,就可以遷移它。

npx prisma migrate dev --name init

將會產生一個migration.sql文件,並在Supabase端建立一個資料表。

建立連接到 Supabase 的 API

建立一個連線API,將輸入的值儲存到Supabase。

在您的專案中安裝 Prisma Client。

npm install @prisma/client

連接到 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();
  }
};

GET 函數是從資料庫中檢索所有記錄的 API,findMany() 方法檢索所有符合條件的記錄。 Prisma.memo.findMany() 中的「memo」是模式名稱。

POST 函數是一種向資料庫新增資料的 API,使用 create() 建立。

另外,還有delete、update等方法,即使無法寫SQL語句,也可以像JavaScript一樣做。

到這裡,一切就緒了。

您所要做的就是將您之前編寫的 API 帶入 page.tsx 並將其合併。

'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>
  );
}

它保存在 Supabase 端!

這次,我依靠 Gemini 創建了一個粗略的輪廓,但如果我可以使用資料庫來保存值,那麼我可以創建的功能和應用程式的範圍將會更廣泛!

我先入為主地認為後端會很難,但能夠使用 GUI 工具管理資料庫很容易理解,並且降低了資料庫整合的門檻!

耶!

撰稿人

我使用 JavaScript、React 和 Next.js 開發前端項目,專注於標記語言。當我參與開發的網站成功發佈時,我感到無比欣慰!我的嗜好是彈吉他。我既喜歡寫程式碼,也喜歡玩程式碼!

Hiratchi

前端工程師 / 2022年入職

我們以可靠的團隊結構和快速的回​​應能力而自豪。

在 Liberogic,我們經驗豐富的員工積極推動專案進展,這也是我們受到客戶高度評價的原因。
我們確保專案經理和主管得到合理分配,以確保整個專案的順利進行。 我們避免因全額承諾而導致不必要的成本增加,並將資源分配給合適的人員和合適的職位,並以快速掌握工作內容、創建和提交預算而聞名。

請注意,我們不主動提供 SES 等現場服務。

我們支援幾乎所有主流的專案管理和聊天工具,包括 Slack、Teams、Redmine、Backlog、Asana、Jira、Notion、Google Workspace、Zoom 和 Webex。

在使用 SES 和離岸的大型專案中您是否遇到任何技術問題或擔心如何解決這些問題?

案例研究