如何将 Prisma 与 Hono 结合使用
介绍
¥Introduction
Prisma ORM 提供类型安全的数据库访问,Hono 专为快速、轻量级的 Web 应用而构建。结合 Prisma Postgres,你将获得一个快速、轻量级的后端,可以通过 Node.js、Cloudflare 或许多其他运行时进行部署。
¥Prisma ORM offers type-safe database access, and Hono is built for fast, lightweight web apps. Together with Prisma Postgres, you get a fast, lightweight backend, that can be deployed through Node.js, Cloudflare, or many other runtimes.
在本指南中,你将学习如何在 Hono 后端应用中将 Prisma ORM 与 Prisma Postgres 数据库集成。你可以在 GitHub 上找到本指南的完整示例。
¥In this guide, you'll learn to integrate Prisma ORM with a Prisma Postgres database in a Hono backend application. You can find a complete example of this guide on GitHub.
先决条件
¥Prerequisites
1. 设置你的项目
¥ Set up your project
创建一个新的 Hono 项目:
¥Create a new Hono project:
npm create hono@latest
-
目标目录?
my-app¥Target directory?
my-app -
你想使用哪个模板?
nodejs¥Which template do you want to use?
nodejs -
安装依赖?(推荐)
Yes¥Install dependencies? (recommended)
Yes -
你想使用哪个软件包管理器?
npm¥Which package manager do you want to use?
npm
2. 安装和配置 Prisma
¥ Install and configure Prisma
2.1.安装依赖
¥2.1. Install dependencies
要开始使用 Prisma,你需要安装一些依赖:
¥To get started with Prisma, you'll need to install a few dependencies:
- Prisma Postgres (recommended)
- Other databases
npm install prisma --save-dev
npm install @prisma/extension-accelerate @prisma/client dotenv
npm install prisma --save-dev
npm install @prisma/client dotenv
安装完成后,请在你的项目中初始化 Prisma:
¥Once installed, initialize Prisma in your project:
npx prisma init --db --output ../src/generated/prisma
在设置 Prisma Postgres 数据库时,你需要回答几个问题。选择离你最近的区域,并为数据库选择一个容易记住的名称,例如 "我的 Hono 项目"
¥You'll need to answer a few questions while setting up your Prisma Postgres database. Select the region closest to your location and a memorable name for your database like "My Hono Project"
这将造成:
¥This will create:
-
一个包含
schema.prisma文件的prisma/目录¥A
prisma/directory with aschema.prismafile -
A
prisma.config.tswith your Prisma configuration -
一个已设置
DATABASE_URL的.env文件¥A
.envfile with aDATABASE_URLalready set
2.2.定义 Prisma Schema
¥2.2. Define your Prisma Schema
在 prisma/schema.prisma 文件中,添加以下模型,并将生成器更改为使用 prisma-client 提供程序:
¥In the prisma/schema.prisma file, add the following models and change the generator to use the prisma-client provider:
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
authorId Int
author User @relation(fields: [authorId], references: [id])
}
这将创建两个模型:User 和 Post,它们之间存在一对多关系。
¥This creates two models: User and Post, with a one-to-many relationship between them.
In prisma.config.ts, import dotenv at the top of the file
import { defineConfig, env } from "prisma/config";
import "dotenv/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
engine: "classic",
datasource: {
url: env("DATABASE_URL"),
},
});
2.3.配置 Prisma 客户端生成器
¥2.3. Configure the Prisma Client generator
现在,运行以下命令创建数据库表并生成 Prisma 客户端:
¥Now, run the following command to create the database tables and generate the Prisma Client:
npx prisma migrate dev --name init
2.4.种子数据库
¥2.4. Seed the database
让我们添加一些种子数据,以便用示例用户和帖子填充数据库。
¥Let's add some seed data to populate the database with sample users and posts.
在 prisma/ 目录中创建一个名为 seed.ts 的新文件:
¥Create a new file called seed.ts in the prisma/ directory:
import { PrismaClient, Prisma } from "../src/generated/prisma/client.js";
const prisma = new PrismaClient();
const userData: Prisma.UserCreateInput[] = [
{
name: "Alice",
email: "alice@prisma.io",
posts: {
create: [
{
title: "Join the Prisma Discord",
content: "https://pris.ly/discord",
published: true,
},
{
title: "Prisma on YouTube",
content: "https://pris.ly/youtube",
},
],
},
},
{
name: "Bob",
email: "bob@prisma.io",
posts: {
create: [
{
title: "Follow Prisma on Twitter",
content: "https://www.twitter.com/prisma",
published: true,
},
],
},
},
];
export async function main() {
for (const u of userData) {
await prisma.user.create({ data: u });
}
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
现在,通过更新 prisma.config.ts 来告诉 Prisma 如何运行此脚本:
¥Now, tell Prisma how to run this script by updating your prisma.config.ts:
import { defineConfig, env } from "prisma/config";
import "dotenv/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: "tsx prisma/seed.ts"
},
engine: "classic",
datasource: {
url: env("DATABASE_URL"),
},
});
运行种子脚本:
¥Run the seed script:
npx prisma db seed
打开 Prisma Studio 检查你的数据:
¥And open Prisma Studio to inspect your data:
npx prisma studio
3. 将 Prisma 集成到 Hono
¥ Integrate Prisma into Hono
3.1.创建 Prisma 中间件
¥3.1. Create a Prisma middleware
在 /src 中,创建一个 lib 目录并在其中创建一个 prisma.ts 文件。此文件将用于创建和导出你的 Prisma 客户端实例。按如下方式设置 Prisma 客户端:
¥Inside of /src, create a lib directory and a prisma.ts file inside it. This file will be used to create and export your Prisma Client instance. Set up the Prisma client like this:
- Prisma Postgres (recommended)
- Other databases
import type { Context, Next } from 'hono';
import { PrismaClient } from '../generated/prisma/client.js';
import { withAccelerate } from '@prisma/extension-accelerate';
import "dotenv/config";
function withPrisma(c: Context, next: Next) {
if (!c.get('prisma')) {
const databaseUrl = process.env.DATABASE_URL;
if (!databaseUrl) {
throw new Error('DATABASE_URL is not set');
}
const prisma = new PrismaClient({ datasourceUrl: databaseUrl })
.$extends(withAccelerate());
c.set('prisma', prisma);
}
return next();
}
export default withPrisma;
import type { Context, Next } from 'hono';
import { PrismaClient } from '../generated/prisma/client.js';
import "dotenv/config";
const databaseUrl = process.env.DATABASE_URL;
if (!databaseUrl) {
throw new Error('DATABASE_URL is not set');
}
const prisma = new PrismaClient({ datasourceUrl: databaseUrl });
function withPrisma(c: Context, next: Next) {
if (!c.get('prisma')) {
c.set('prisma', prisma);
}
return next();
}
export default withPrisma;
我们建议使用连接池(例如 Prisma 加速)来高效管理数据库连接。
¥We recommend using a connection pooler (like Prisma Accelerate) to manage database connections efficiently.
如果你选择不使用 PrismaClient,请在长期环境中(例如,Node.js 服务器)实例化单个 PrismaClient 并在请求之间重复使用它,以避免耗尽数据库连接。在无服务器环境中或使用池化器(例如 Accelerate)时,可以为每个请求创建一个客户端。
¥If you choose not to use one, in long-lived environments (for example, a Node.js server) instantiate a single PrismaClient and reuse it across requests to avoid exhausting database connections. In serverless environments or when using a pooler (for example, Accelerate), creating a client per request is acceptable.
3.2 环境变量和类型
¥3.2 Environment Variables & Types
默认情况下,Hono 不会从 .env 加载任何环境变量。dotenv 处理此问题,并将读取该文件并通过 process.env 公开它们。Hono can get additional types to know that the withPrisma middleware will set a prisma key on the Hono context
¥By default, Hono does not load any environment variables from a .env. dotenv handles this and will be read that file and expose them via process.env. Hono can get additional types to know that the withPrisma middleware will set a prisma
key on the Hono context
import { Hono } from "hono";
import { serve } from "@hono/node-server";
import type { PrismaClient } from "./generated/prisma/client.js";
type ContextWithPrisma = {
Variables: {
prisma: PrismaClient;
};
};
const app = new Hono<ContextWithPrisma>();
app.get("/", (c) => {
return c.text("Hello Hono!");
});
serve(
{
fetch: app.fetch,
port: 3000,
},
(info) => {
console.log(`Server is running on http://localhost:${info.port}`);
}
);
如果使用 Cloudflare Workers,环境变量将自动设置为 Hono 的上下文,因此可以跳过 dotenv。
¥If using Cloudflare Workers, the environment variables will automatically be set to Hono's contenxt, so dotenv can be skipped.
3.3.创建 GET 路由
¥3.3. Create A GET Route
使用 Hono 的 app.get 函数从数据库获取数据。这将执行任何数据库查询并以 JSON 格式返回数据。
¥Fetch data from the database using Hono's app.get function. This will perform any database queries
and return the data as JSON.
在 src/index.ts 中创建一个新路由:
¥Create a new route inside of src/index.ts:
现在,创建一个 GET 路由,从你的数据库获取 Users 数据,并确保通过将每个用户的 Posts 添加到 include 字段来包含它们:
¥Now, create a GET route that fetches the Users data from your database, making sure to include each user's Posts by adding them to the include field:
import withPrisma from './lib/prisma.js';
app.get('/users', withPrisma, async (c) => {
const prisma = c.get('prisma');
const users = await prisma.user.findMany({
include: { posts: true },
});
return c.json({ users });
});
3.4.显示数据
¥3.4. Display The Data
通过调用 package.json 中的 dev 脚本启动 Hono 应用
¥Start the Hono app by call the dev script in the package.json
npm run dev
应该会打印出“服务器正在 http://localhost:3000 上运行”的日志。从这里,可以通过访问 http://localhost:3000/users 或从命令行运行 curl 来查看数据。
¥There should be a "Server is running on http://localhost:3000" log printed out. From here, the data
can be viewed by visting http://localhost:3000/users or by running curl from the command line
curl http://localhost:3000/users | jq
你已完成!你已经使用 Prisma 创建了一个连接到 Prisma Postgres 数据库的 Hono 应用。对于后续步骤,你可以参考以下资源以及扩展项目的后续步骤。
¥You're done! You've created a Hono app with Prisma that's connected to a Prisma Postgres database. For next steps there are some resources below for you to explore as well as next steps for expanding your project.
后续步骤
¥Next Steps
现在,你已经拥有一个连接到 Prisma Postgres 数据库的 Hono 应用,你可以:
¥Now that you have a working Hono app connected to a Prisma Postgres database, you can:
-
使用更多模型和关系扩展你的 Prisma 模式
¥Extend your Prisma schema with more models and relationships
-
添加创建/更新/删除路由和表单
¥Add create/update/delete routes and forms
-
探索身份验证和验证
¥Explore authentication and validation
-
使用 Prisma Postgres 启用查询缓存以获得更好的性能
¥Enable query caching with Prisma Postgres for better performance
更多信息
¥More Info
Stay connected with Prisma
Continue your Prisma journey by connecting with our active community. Stay informed, get involved, and collaborate with other developers:
- Follow us on X for announcements, live events and useful tips.
- Join our Discord to ask questions, talk to the community, and get active support through conversations.
- Subscribe on YouTube for tutorials, demos, and streams.
- Engage on GitHub by starring the repository, reporting issues, or contributing to an issue.