构建基于 Prisma 和 PostgreSQL 的 REST API 的方法指南
国内基于 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 了
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 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
同时也可以查看数据库客户端,检查数据是否已经插入表中
至此,我们已经顺利完成了数据库的写入与读取,在后续的步骤中,我们将开始开发一系列简单的接口
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 数据。
好了,目前你已经实现了一个简单的 Restful API,后续可以实现更多的接口,如:
HTTP 方法 | 路由 | 描述 |
---|---|---|
GET | /feed | 获取所有 Post |
GET | /post/:id | 根据 ID 查询 Post 详情 |
POST | /user | 创建一个新 User |
POST | /post | 创建一个新 Post(草稿) |
PUT | /post/publish/:id | 发布指定 ID 的 Post |
DELETE | post/:id | 删除指定 ID 的 Post |
结论
在本文中,你从零开始实现了一个 Restful API 的程序,你也可以基于此开发更多的功能,并使用 Prisma Migrate 来丰富你的数据库结构以实现更多的扩展,具体可以访问 Prisma 的官方文档。
转载自:https://juejin.cn/post/7242872705253621816