使用ExpressJS和Supabase构建CRUD应用程序
#node #express #supabase #backend

即使我是前端开发人员,我一直想知道后端是如何工作的,并且随着时间的流逝,我尝试了许多服务器端技术,例如express with mongodb,ASP.NET(c#)和Laravel(PHP)。但是,我最近的联系是当我从采访中获得了带回家测试的时候:我的任务是建立一个简单的博客API,并使用像Postgres这样的关系数据库。因此,我决定使用supabase,因为它在Postgres上运行。

在本教程中,您将学习如何使用Express和Supabase创建CRUD API。如official documentation中所述,Express是在Node.js顶部构建的最受欢迎的Web框架之一,用于Web和移动应用程序。它简化了创建服务器,路由和中间件。

CRUD是指服务服务器执行的一组操作的常见方法。首字母缩写词代表创建,阅读,更新和删除。下表总结了其相应的HTTP方法的建议返回值:

CRUD Table

什么是supabase,为什么要选择它?

Supabase是一种开源后端服务,提供了一套工具来帮助开发人员快速构建和扩展应用程序,其中包括:

  • 数据库:每个项目都使用引擎盖下的Postgres,这是一个关系数据库。
  • 身份验证:您可以将登录和注册添加到您的应用中。
  • 存储:您可以存储,组织和提供大文件。
  • 边缘函数:这些有助于执行最接近用户的代码以获得快速体验。

我们将使用Supabase与Express App。

先决条件

要开始本教程,您需要进行以下设置/安装:

express和supabase将作为依赖项安装,就像设置项目后一样。因此,让我们开始。

项目设置

首先,使用以下命令创建一个新文件夹并初始化一个新的node.js项目。

mkdir supabase-crud && cd supabase-crud 
npm init -y

该命令创建一个称为 supabase-crud>的文件夹,并使用 package.json.json 文件初始化node.js项目,该文件应该看起来像这样:

{
  "name": "supabase-crud",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

您不必这样做,但是您可以像描述和作者一样更新JSON文件。类似:

{
  "description": "Express app with Supabase",
  "author": "John Ademoye",
}

在文件夹中创建一个新文件,并将其命名 server.js 。这将作为您的node.js应用程序的入口点。

安装Express和其他依赖关系

现在安装express library并用以下代码旋转服务器:

import express from "express";

const app = express();

app.get("/", (_, response) =>
  response.json({ info: "Express app with Supabase" })
);

app.listen(3000, () =>
  console.log(
    new Date().toLocaleTimeString() + `: Server is running on port ${3000}...`
  )
);

上面的代码在“/”路线下返回{ info: "Express app with Supabase" },并使用时间戳在终端上记录Server is running on port 3000...

现在让我们看看是否是这种情况。使用:
运行应用程序

node server.js

如果一切顺利,您应该使用REST客户端获得这样的东西:

Get Home Endpoint

您也可以转到浏览器中的URL,您应该得到相同的响应:

Express browser home

但是我更喜欢使用REST客户端,因为我不必切换Windows。

每次更改server.js时,我都必须重新运行文件。因此,为避免必须这样做,请安装nodemon以观看文件以进行更改。尽管Node V18.11.0具有内置的手表模式,但它仍然是实验性的。

我还想将端口号作为dotenv文件中的环境变量以及其他常数(例如数据库名称和键)。 DotEnv是一个软件包,它会自动将环境变量从.env文件加载到process.env object中。

因此,请使用命令安装dotenv:npm i dotenv。然后在您的应用中,需要并配置这样的包:

import express from "express";
import env from "dotenv";

env.config();

const app = express();

app.get("/", (_, response) =>
  response.json({ info: "Express app with Supabase" })
);

app.listen(process.env.PORT, () =>
  console.log(
    new Date().toLocaleTimeString() +
      `: Server is running on port ${process.env.PORT}...`
  )
);

要使用nodemon,打开package.json文件并使用以下配置修改脚本:

"scripts": {
    "dev": "nodemon server.js"
  },

这就是项目文件夹结构的外观:

📁 SUPABASE-CRUD
∟📁 node_modules
∟📄 .env
∟📄 package-lock.json
∟📄 package.json
∟📄 requests.http
∟📄 server.js

设置supabase

创建Supabase帐户后,您在登录时提示到仪表板,其中包含所有项目。如果这是您第一次使用Supabase,那么您不应该在那里看到任何项目。因此,创建一个新项目:

New project supabqse

项目在组织下进行。如果您还没有一个组织,请创建一个组织;我已经有一个组织。

New project org

然后创建一个新项目并将其命名 supabase-crud 。密码将自动生成,因此创建项目后只需提交表格即可。

New project form

现在 supabase-crud 具有其页面。向下滚动到可以找到URL和API键的项目API部分。复制URL并键并将它们保存为database_url和database_key在.env文件中。

New project and API

现在返回项目页面的顶部。通过Table editor按钮转到表格,然后创建一个新表:

Table editor button

命名表帖子和像博客数据库一样的描述很好。

Create a new table

用一些虚拟数据插入一行,以手动保存。

Insert a row

在应用程序中设置supabase

首先,安装库:

npm install @supabase/supabase-js

然后导入createCleint与数据库建立连接。 createClient将数据库URL和键作为参数:

import { createClient } from '@supabase/supabase-js'

const supabase = createClient(process.env.DATABASE_URL,process.env.DATABASE_KEY);

到目前为止,服务器文件看起来像这样:

import express from "express";
import env from "dotenv";

import { createClient } from "@supabase/supabase-js";

env.config();

const supabase = createClient(process.env.DATABASE_URL,process.env.DATABASE_KEY);

// Services 

app.listen(process.env.PORT, () =>
  console.log(
    new Date().toLocaleTimeString() +
      `: Server is running on port ${process.env.PORT}...`
  )
);

创建路线

我们将定义这些处理CRUD操作的路线:

  • 获取所有文章
  • 获取文章
  • 发表文章
  • 更新文章
  • 删除文章

我们将在此处使用Supabase documentation作为指南:

  • 要获取所有文章,请在没有任何参数的情况下从其中指定它们的使用。
// Get all articles

app.get("/articles", async (_, response) => {
  try {
    const { data, error } = await supabase.from("posts").select();
    console.log(data);
    return response.send(data);
  } catch (error) {
    return response.send({ error });
  }
});

  • 要获取特定的文章,请再次指定源表并使用select。然后从URL传递ID,该ID可以通过requests.params.id访问,作为对eq的参数,以获取其id等于参数对象中的文章。

// Get an article

app.get("/articles/:id", async (request, response) => {
  try {
    const { data, error } = await supabase
      .from("posts")
      .select()
      .eq("id", request.params.id)
    console.log(data);
    return response.send(data);
  } catch (error) {
    return response.send({ error });
  }
});

  • 要发布文章,您需要在有效载荷中指定titlebody,可以通过请求对象访问。然后将其传递给插入方法,然后将其写入数据库。如果有错误,则其状态代码为400。
// Post an article

app.post("/articles", async (request, response) => {
  try {
    console.log(request.body);
    const { data, error } = await supabase.from("posts").insert(request.body);
    if (error) {
      return response.status(400).json(error);
    }
    response.status(200).json(request.body);
  } catch (error) {
    response.send({ error });
  }
});

  • 要更新特定文章,该文章的id在URL中传递,请与三元运营商联系需要更新的内容。然后选择要使用eq更新的文章。
// Update an article

app.put("/articles/:id", async (request, response) => {
  console.log(request.params);
  try {
    const { data: updatedData, error: updatedError } = await supabase
      .from("posts")
      .update({
        title: request.body.title ? request.body.title : data[0].title,
        body: request.body.body ? request.body.body : data[0].body,
      })
      .eq("id", request.params.id);
    const { data, err } = await supabase.from("posts").select();
    return response.status(200).send(data);
  } catch (error) {
    response.send({ error });
  }
});

  • 要删除文章,也需要id;使用Supabase Delete函数执行此操作。首先进行删除,然后获取所有文章,这些文章不再包含已删除的文章。
// Delete an article

app.delete("/articles/:id", async (request, response) => {
  try {
    const { data, error } = await supabase
      .from("posts")
      .delete()
      .eq("id", request.params.id);
    const { datar, errorr } = await supabase.from("posts").select();
    if (error) {
      return response.status(400).json(error);
    }
    return response.send(datar);
  } catch (error) {
    response.send({ error });
  }
});

结论

在本文中,您学习了如何使用Express和Supabase制作CRUD应用程序。它开始引入相关技术:Express和Supabase,也强调了您应该在项目中使用Supabase的原因。

本文还涵盖了旋转Express服务器,设置Supabase项目并创建处理应用程序必要的CRUD操作的路线。

该应用程序发表在Supabase Launch Week上。大约4个月前,我已经构建了一个类似的应用程序,所以我没有费心将这一特定的应用程序推向Github。因此,请随意克隆original project并查看其工作原理。


我希望本文有帮助,您从中学到了一些东西。作为技术作家和内容创建者,我热衷于分享我的知识(包括技巧和建议),并帮助其他人实现自己的目标,尤其是那些刚刚从事技术的目标。您可以在我的社交媒体资料和博客here上与我联系。