切换显示语言

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端创建数据表。

创建 API 以连接到 Supabase

创建一个连接 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 和离岸的大型项目中您是否遇到任何技术问题或担心如何解决这些问题?

案例研究