likes
comments
collection
share

构建基于 Prisma 和 PostgreSQL 的 REST API 的方法指南

作者站长头像
站长
· 阅读数 14

国内基于 Prisma 构建数据库的企业应该不多,主要都被 Java 技术栈占了,但作为一个精于前端的 Indie Hacker 必须要了解如何快速开发可用的 Restful 的 API,才能创造更多的应用。学 Java 太晚了,学 Ruby 似乎也太晚了,不如就从 Node 切入吧,都是 JS 语法容易上手,后续也可以学习更多其他工具,如 NextJS,不过咱首先要学会构建数据库,那就从 Prisma 开始。

介绍

Prisma 是用于 Node.js 和 TypeScript 的开源 ORM(对象关系映射)工具。它由以下三个主要组件组成:

  • Prisma Client:一个自动生成且类型安全的查询构建器。
  • Prisma Migrate:一个强大的数据建模和迁移系统。
  • Prisma Studio:一个用于查看和编辑数据库中数据的图形用户界面。

这些工具旨在提高应用程序开发者在数据库工作流中的生产力。Prisma 的其中一个主要优点是提供了一定程度的抽象:应用程序开发者在使用 Prisma 时可以以更直观的方式思考数据,而不需要去研究复杂的 SQL 查询或模式迁移。

在本教程中,您将使用 Prisma 和 PostgreSQL 数据库,使用 TypeScript 构建一个小型博客应用的 REST API。您将通过 Docker 在本地设置 PostgreSQL 数据库,并使用 Express 实现 REST API 路由。在教程结束时,您将在本地计算机上运行一个可以响应各种 HTTP 请求并读写数据库中数据的 Web 服务器。

先决条件

本教程假设您已满足以下条件:

  • 在您的计算机上安装了 Node.js 版本 14 或更高版本。
  • 在您的计算机上安装了 Docker(用于运行 PostgreSQL 数据库)。

如果你对 TypeScript 和 REST API 比较熟悉有助于理解本教程,但并不是必须的。

0x01 — 创建你的 TypeScript 项目

先用 npm 初始化一个项目,新建一个项目文件夹,然后进入文件夹,并执行 npm init -y

mkdir my-app
cd my-app
npm init -y

注意,这里的 -y 选项意味着你将跳过命令的交互式提示。如果你想查看这些提示,可以不加 -y 。

然后执行以下命令:

npm install typescript ts-node @types/node --save-dev

安装3个开发依赖包:

  • typescript:TypeScript 工具链。
  • ts-node:一个可以在不预先编译为 JavaScript 的情况下运行 TypeScript 应用的包。
  • @types/node:Node.js 的 TypeScript 类型定义。

然后执行 npx tsc --init --outDir dist 初始化 tsconfig.json ,详细的命令行指南可以参考这里

至此我们已经使用 npm 设置了最简单 TypeScript 项目。接下来,将使用 Docker 设置 PostgreSQL 数据库,并使用 Prisma 来连接它。

0x02 — 使用 PostgreSQL 设置 Prisma

在这一步中,我们将安装 Prisma CLI,创建初始 Prisma schema 文件,并使用 Docker 设置 PostgreSQL 数据库并用 Prisma 来连接它。Prisma schema 是 Prisma 的主要配置文件,这里面包含数据库的表结构信息。

首先,使用以下命令安装 Prisma CLI:

npm install prisma --save-dev

作为一种最佳实践,建议在项目本地安装 Prisma CLI(而不是全局安装)。这种做法有助于避免机器上有多个 Prisma 项目时的版本冲突。

接着,我们将使用 Docker 设置 PostgreSQL 数据库。使用以下命令创建一个新的 Docker Compose 文件:

touch docker-compose.yml

然后在 VSCode 中打开并编辑它。

version: '3.8'
services:
  db:
    image: postgres:13
    restart: unless-stopped
    ports:
      - '5432:5432'
    environment:
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=admin
      - POSTGRES_DB=postgres
    volumes:
      - pgdata:/var/lib/postgresql/data

这里主要配置下用户名和密码,以访问 Docker 中的数据库。然后输入以下命令启动 Docker 容器,并安装数据库

docker compose up -d

如果出现端口冲突,可以尝试关闭其他 Docker 容器,或者更改外部端口号。成功启动可以通过 Docker App 查看运行状态。

构建基于 Prisma 和 PostgreSQL 的 REST API 的方法指南

数据库搞定之后,接着就是初始化 Prisma 了

npx prisma init

以上命令会创建 schema.prisma 文件,同时还创建了 .env 环境变量文件,接着需要修改其中的 DATABASE_URL 来确保数据库顺利连接。主要是修改用户名密码和数据库名称。

在这一节中,我们使用 Docker 设置了 PostgreSQL 数据库,安装了 Prisma CLI,并通过环境变量将 Prisma 连接到了数据库。在下一节中,我们将定义数据模型并创建数据库表。

0x03 — 定义数据模型并创建数据库表

在这一节中,我们将在 schema.prisma 文件中定义数据模型,数据模型将通过 Prisma Migrate 组件映射到数据库中,具体表现为生成建表语句并在数据库中执行。

现在让我们来编辑 schema.prisma 文件

// 在 datasource db 块之后添加 ...
model User {
  id    Int     @default(autoincrement()) @id
  email String  @unique
  name  String?
  posts Post[]
}

model Post {
  id        Int     @default(autoincrement()) @id
  title     String
  content   String?
  published Boolean @default(false)
  author    User?   @relation(fields: [authorId], references: [id])
  authorId  Int?
}

这里定义两个模型:User 和 Post。每个模型都有一些字段,这些字段代表模型的属性。这些模型将映射到数据库表,字段代表各个列。

两个模型之间存在一对多的关系,通过 User 和 Post 上的 posts 和 author 字段来绑定关系。这意味着一个 User 可以与多个 Post 相关联。

(暂时可以先不关心 schema 的具体写法,将另写文章详述,这里先体验使用 Prisma 建表)

然后我们可以使用以下命令行来在数据库中建表。

npx prisma migrate dev --name init

执行之后,我们将在 prisma 文件夹中找到新生成的 sql 文件

-- CreateTable
CREATE TABLE "User" (
    "id" SERIAL NOT NULL,
    "email" TEXT NOT NULL,
    "name" TEXT,

    CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "Post" (
    "id" SERIAL NOT NULL,
    "title" TEXT NOT NULL,
    "content" TEXT,
    "published" BOOLEAN NOT NULL DEFAULT false,
    "authorId" INTEGER,

    CONSTRAINT "Post_pkey" PRIMARY KEY ("id")
);

-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");

-- AddForeignKey
ALTER TABLE "Post" ADD CONSTRAINT "Post_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;

此时我们可以打开 PostgreSQL 客户端查看建表情况:

构建基于 Prisma 和 PostgreSQL 的 REST API 的方法指南

在这一节中,我们在 Prisma schema 中定义了数据模型,并使用 Prisma Migrate 创建了相应的数据库表。在下一节中,我们将在项目中使用 Prisma Client,以便可以查询数据库。

0x04 — 使用 Prisma Client 执行简单查询脚本

Prisma Client 是一个自动生成的、类型安全的查询构建器,可以在 Node.js 或 TypeScript 应用程序中使用它以编程方式读取和写入数据库中的数据。我们将在 REST API 的路由中通过它来访问数据库,取代传统的 ORM、纯 SQL 查询、自定义数据访问层,或与数据库通信的任何其他方法。

在这一节中,我们将安装 Prisma Client 并熟悉通过它来发送的查询操作。

npm install @prisma/client

接下来在项目根目录创建一个 src 文件夹,并在 src 文件夹中创建 index.ts 文件

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

async function main() {
  // ... 在这里编写你的查询脚本
}

main()
  .catch((e) => console.error(e))
  .finally(async () => await prisma.$disconnect())

简单解释下这里的代码:

  • 引入 PrismaClient 类,并实例化
  • 定义一个异步处理的 main 函数,在其中编写数据库脚本,在调用它之后及时断开数据库连接
import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

async function main() {
  const newUser = await prisma.user.create({
    data: {
      name: 'Alice',
      email: 'alice@prisma.io',
      posts: {
        create: {
          title: 'Hello World',
        },
      },
    },
  })
  console.log('Created new user: ', newUser)

  const allUsers = await prisma.user.findMany({
    include: { posts: true },
  })
  console.log('All users: ')
  console.dir(allUsers, { depth: null })
}

main()
  .catch((e) => console.error(e))
  .finally(async () => await prisma.$disconnect())

以上代码中,使用了两次 prisma 数据库执行操作

  • create:创建一个新的 User 记录,并使用内嵌写入法同时创建了一个属于该用户的 Post 记录。
  • findMany:获取所有用户记录,并附带该用户下的所有 Post 记录。

现在我们来执行以下该文件,看看输出的结果:

npx ts-node src/index.ts

构建基于 Prisma 和 PostgreSQL 的 REST API 的方法指南

同时也可以查看数据库客户端,检查数据是否已经插入表中

构建基于 Prisma 和 PostgreSQL 的 REST API 的方法指南

至此,我们已经顺利完成了数据库的写入与读取,在后续的步骤中,我们将开始开发一系列简单的接口

0x05 — 实现第一个 Restful API 接口

在这一节中,我们将安装 Express。Express 是一个流行的 Node.js 网络框架,我们将在此项目中使用它来实现 Restful API 路由。这里我们将要实现的第一个路由使用 GET 请求从 API 获取所有用户数据。用户数据是通过 Prisma Client 从数据库中检索。

首先,我们先安装 Express

npm install express

然后需要在开发依赖中安装 Express 的类型包

npm install @types/express --save-dev

安装完毕后,我们重新编辑 src/index.ts 文件(将原来的所有代码清空,并添加以下代码)

import { PrismaClient } from '@prisma/client'
import express from 'express'

const prisma = new PrismaClient()
const app = express()

app.use(express.json())

// 这里添加了一个获取所有用户的 GET 接口
app.get('/users', async (req, res) => {
  const users = await prisma.user.findMany()
  res.json(users)
})

app.listen(3000, () =>
  console.log('REST API server ready at: http://localhost:3000'),
)

编辑完成后保存文件,然后执行以下命令启动服务器:

npx ts-node src/index.ts

然后在浏览器中访问 http://localhost:3000/users ,可以看到返回的 JSON 数据。

构建基于 Prisma 和 PostgreSQL 的 REST API 的方法指南

好了,目前你已经实现了一个简单的 Restful API,后续可以实现更多的接口,如:

HTTP 方法路由描述
GET/feed获取所有 Post
GET/post/:id根据 ID 查询 Post 详情
POST/user创建一个新 User
POST/post创建一个新 Post(草稿)
PUT/post/publish/:id发布指定 ID 的 Post
DELETEpost/:id删除指定 ID 的 Post

结论

在本文中,你从零开始实现了一个 Restful API 的程序,你也可以基于此开发更多的功能,并使用 Prisma Migrate 来丰富你的数据库结构以实现更多的扩展,具体可以访问 Prisma 的官方文档