新闻详情

新闻详情

首页 / 资讯中心 / 详情

HowToGraphQL(typescript-helix 教程):用 Prisma Client 把 GraphQL Server 与数据库连接起来

发布时间:2026/9/25 3:25:34来源:尧图网络
HowToGraphQL(typescript-helix 教程):用 Prisma Client 把 GraphQL Server 与数据库连接起来
【免费下载链接】howtographqlThe Fullstack Tutorial for GraphQL项目地址https://gitcode.com/gh_mirrors/ho/howtographql点击查看免费下载本篇基于 howtographql 仓库中 TypeScript Fastify GraphQL-Helix 后端教程的《Connecting The Server and Database with Prisma Client》一章展开。核心主题是在已经跑通 in-memory 版 Hacker News API 之后如何通过 GraphQL 的context参数把 Prisma Client 实例注入到 resolver 中从而让feed查询与post变更读写真正的 SQLite 数据库。读完本篇你将掌握 GraphQLcontext的注入与类型化方式、resolver 从假数据切换到 Prisma CRUD API 的完整重构流程以及如何用 GraphiQL 和 Prisma Studio 验证持久化结果。前置背景这个教程走到哪一步了该章节属于hackernews-node-ts项目一个从零搭建的 Hacker News 克隆 API技术栈为Node.js TypeScriptts-node直接运行.tsfastify作为 HTTP 服务器graphql-helix提供processRequest、getGraphQLParameters、sendResult等执行管道工具Prisma 3 访问 SQLite数据库初始化在上一章完成参见 Adding a Database。在此之前src/schema.ts中的feed与post都只操作内存数组linkspost通过idCount自增生成link-1、link-2这类 id见 A Simple Mutation。服务一重启数据全丢。本章的目标就是消除这个痛点。上一章Adding a Database已完成的工作包括npm install --save-dev prisma prisma/client安装 CLI 与 Clientnpx prisma init生成prisma/schema.prisma其中定义了 SQLite 数据源、prisma-client-jsgenerator 和Link模型datasource db { provider sqlite url file:./dev.db } generator client { provider prisma-client-js } model Link { id Int id default(autoincrement()) createdAt DateTime default(now()) description String url String }npx prisma migrate dev迁移名init创建了数据库文件和Link表Prisma Client 被自动生成到node_modules/prisma/client可用npx prisma generate手动重新生成。本章要做的就是让 GraphQL 服务器用上这个已生成好的 Prisma Client。一、用contextFactory把 Prisma Client 挂到 GraphQLcontext上GraphQL resolver 的context参数所有 GraphQL resolver 函数都会收到四个参数parent、args、context、info。本章用到的是context它是一个普通 JavaScript 对象resolver 链上的每个 resolver 都能读、能写因此它是 resolver 之间通信的天然载体更关键的特性是在 GraphQL 服务器初始化阶段就可以向context写入内容。这意味着可以在 server 启动时把 Prisma Client 实例挂到context上之后在任何 resolver 里通过第三个参数取到它。第一步创建src/context.ts骨架新建文件src/context.ts路径为教程项目hackernews-node-ts内部路径下同先放一个空工厂export async function contextFactory() { return {}; }然后把它接入 GraphQL 执行流程。在src/index.ts中导入contextFactory并把它作为参数传给graphql-helix的processRequest承接 Creating a GraphQL Server 中建立的POST /graphql路由// ... other imports ... import { contextFactory } from ./context; // In your Helix handler, add: const result await processRequest({ request, schema, operationName, contextFactory, query, variables, });从源码结构看graphql-helix的processRequest封装了完整的 GraphQL 执行管道parse、validate、变量解析、context 构建、executecontextFactory正是context 构建这一步的注入点——执行期间产生的context对象会一路传给每个 resolver。第二步把 Prisma Client 注入 context并用 TypeScript 类型约束接下来把真正的数据库连接写进src/context.tsimport { PrismaClient } from prisma/client; const prisma new PrismaClient(); export type GraphQLContext { prisma: PrismaClient; }; export async function contextFactory(): PromiseGraphQLContext { return { prisma, }; }这里有几个值得注意的设计点全局单例连接const prisma new PrismaClient()在模块顶层只创建一次整个服务进程共享同一个 Prisma Client 实例内部维护连接池而不是每个请求 new 一个GraphQLContext类型这是一个纯类型定义用于描述context的结构。它有两个直接收益严格的类型校验——任何 resolver 里写错属性名比如context.prisma写成context.prismaClient都会被 TypeScript 编译器直接报错更好的 IDE 补全——在 resolver 里写context.时能自动补出prisma继续写prisma.link.还能补出 Prisma 生成的全部 CRUD 方法。这正是教程反复强调的靠 Prisma 的自动补全去直觉式地推导 resolver 应该怎么写contextFactory返回PromiseGraphQLContext因为 Prisma Client 初始化可能涉及异步连接建立工厂函数被设计为async。对processRequest来说这没有额外成本执行前会先解析这个 Promise。完成之后所有 resolver 都能访问context.prisma——这正是一个完整的PrismaClient实例来自上一章生成的prisma/client库。二、重构 resolver从内存数组切换到数据库删除假数据导入 Prisma 生成的类型先打开src/schema.ts把内存版实现彻底删掉删除links数组删除idCount变量删除手写的LinkTypeScript 类型type Link { id: string; url: string; description: string }因为 Prisma 已经根据schema.prisma的model Link生成了精确对应的类型。然后把resolvers对象与 import 更新为import { makeExecutableSchema } from graphql-tools/schema; import { GraphQLContext } from ./context; import typeDefs from ./schema.graphql; import { Link } from prisma/client; const resolvers { Query: { info: () This is the API of a Hackernews Clone, feed: async (parent: unknown, args: {}, context: GraphQLContext) { return context.prisma.link.findMany(); }, }, Link: { id: (parent: Link) parent.id, description: (parent: Link) parent.description, url: (parent: Link) parent.url, }, Mutation: { post: ( parent: unknown, args: { description: string; url: string }, context: GraphQLContext ) { const newLink context.prisma.link.create({ data: { url: args.url, description: args.description, }, }); return newLink; }, }, }; export const schema makeExecutableSchema({ typeDefs, resolvers, });注意Link类型现在是从prisma/client导入的生成类型而不是手写的。这与 A Simple Query 一章中手动声明type Link的做法形成对比——数据模型有了单一事实来源prisma/schema.prismaGraphQL 层直接复用它。理解feedresolverfeed: async (parent: unknown, args: {}, context: GraphQLContext) { return context.prisma.link.findMany(); },它的完整数据流是HTTP 请求 →processRequest执行管道 → 调用feedresolver → 经context拿到共享的PrismaClient实例 → 调用上一章在 Prisma Client API 上看到的link.findMany()数据库查询该 API 由schema.prisma中的模型定义自动生成。到这里Prisma/GraphQL 项目的完整系统图景就清楚了Prisma Client 暴露一套与数据模型一一对应的数据库读写查询GraphQL resolver 则负责把args与context转换成这些查询。理解postresolverpost: async ( parent: unknown, args: { description: string; url: string }, context: GraphQLContext ) { const newLink await context.prisma.link.create({ data: { url: args.url, description: args.description, }, }); return newLink; },逻辑与内存版一致只是往links数组里 push 一个对象变成了调用prisma.link.create通过args拿到 GraphQL 操作传入的url与description即Mutation.post(url: String!, description: String!)声明的参数把这两个字段放进create的data参数——Prisma 会根据Link模型自动填充idautoincrement()和createdAtnow()的默认值这与 Adding a Database 中schema.prisma的模型定义直接对应返回新建的 Link 对象。两点补充Prisma CRUD 全部是异步的。newLink本质上是一个Promise所有 Prisma CRUD 操作都是异步的这是由 Prisma 的执行模型决定的。这不会带来问题——底层 HTTP 框架Fastify能够识别并自动 resolve 从 resolver 返回的Promise类型安全的闭环args的形状由 GraphQL schema 保证context.prisma.link.create({ data: ... })的形状由 Prisma 生成类型保证两者之间的映射就发生在 resolver 这一层——这也是为什么教程建议把这段改动亲手敲一遍熟悉 Prisma 的自动补全。三、测试新的持久化实现用npm run dev或npm start启动服务——这两个脚本在 Project Setup 中已配置为ts-node-dev --exit-child src/index.tswatch 模式改文件自动重启和ts-node src/index.ts。然后打开 GraphiQL本教程基于graphql-helix的renderGraphiQL访问入口在 Creating a GraphQL Server 一节中配置于GET /graphql路由本章原文给出的测试地址是http://localhost:3000/playground。发送与之前相同的feed查询和post变更query { feed { id url description } }mutation { post(url: www.prisma.io, description: Prisma replaces traditional ORMs) { id } }与内存版最本质的区别提交进去的 Link 现在被持久化到 SQLite 数据库。因此重启服务后feed查询仍然会返回之前提交过的链接——数据不再随进程消亡。四、用 Prisma Studio 查看数据库Prisma 自带一个数据库 GUIPrisma Studio。它与 TablePlus 之类的传统数据库 GUI 的差异在于它提供一层抽象按 Prisma 数据模型的样子来展示数据而不是直接暴露底层 SQL 表结构。这正是 Prisma 弥合应用层如何组织数据与数据库底层实际如何存储这两层关系的方式之一——长期使用这层抽象有助于建立对模型层与物理表这两个关联但独立层面的直觉。在项目根目录运行npx prisma studio命令执行后会自动打开浏览器标签页默认运行在http://localhost:5555你会看到一个对应Link模型的页签可以直接浏览以及编辑表中的行数据左侧最外层的菜单上可以展开查看所有已定义的模型。结合前文这一章在整条数据链路中处于承上启下的位置schema.prisma模型定义→ Prisma CLI迁移 生成 Client→prisma/client类型安全 CRUD API→contextFactory把 Client 注入 GraphQL 执行→ resolvers把 GraphQL 的args翻译成 Prisma 查询。后续章节Authentication、Subscriptions、Filtering, Pagination and Sorting都会继续在这套context.prisma的基础上演进——例如认证章节会把JWTVerify结果同样挂到context上复用本章建立的同一套 context 注入机制。小结GraphQL 的context参数是 resolver 共享状态的载体且可以在服务器初始化阶段预先填充——这是把基础设施依赖数据库客户端、认证信息等传给 resolver 的惯用手段通过src/context.ts中的contextFactory 模块级单例PrismaClient配合GraphQLContext类型实现了对 Prisma 实例的类型安全注入graphql-helix的processRequest通过新增contextFactory参数即可接入重构 resolver 后feed由prisma.link.findMany()支撑post由prisma.link.create()支撑Link类型直接复用prisma/client的生成类型数据模型与 GraphQL 层共享同一事实来源验证路径GraphiQL 中执行同样的查询/变更重启服务确认数据仍在npx prisma studio打开模型视角的数据库 GUIhttp://localhost:5555直观检查落库结果。赞分享【免费下载链接】howtographqlThe Fullstack Tutorial for GraphQL项目地址https://gitcode.com/gh_mirrors/ho/howtographql点击查看免费下载相关推荐HowToGraphQL用 Prisma Client 将 TypeScript/Apollo GraphQL 服务器接入 SQLite 数据库HowToGraphQL用 Prisma Client 将 TypeScript/Apollo GraphQL 服务器接入 SQLite 数据库 本文基于 HHowToGraphQL TypeScript Helix 教程导读用 Node.js、Fastify 与 Prisma 从零构建 GraphQL 服务器HowToGraphQL TypeScript Helix 教程导读用 Node.js、Fastify 与 Prisma 从零构建 GraphQL 服务器howtographql typescript-helix 教程用 Fastify Prisma 为 GraphQL API 实现过滤、分页与排序howtographql typescript helix 教程用 Fastify Prisma 为 GraphQL API 实现过滤、分页与排序 本篇基上一篇如何用MPh轻松实现COMSOL Multiphysics自动化仿真新手入门终极指南下一篇Gatsby 服务端渲染Server-Side Rendering指南从运行时 HTML 生成到构建期静态页面创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Havoc Teamserver 配置体系解析:HCL 配置语言工具包与 yaotl Profile 的完整实现 2026/9/25 4:10:23

Havoc Teamserver 配置体系解析:HCL 配置语言工具包与 yaotl Profile 的完整实现

网络安全 【免费下载链接】Havoc The Havoc Framework 项目地址: https://gitcode.com/gh_mirrors/ha/Havoc 点击查看 免费下载 HCL(HashiCorp Configuration Language)工具包是 Havoc Teamserver 的 profile 配置文件(.yaotl&am…

阅读更多 →
随机波浪速度与波浪力计算:从JONSWAP谱到Morison方程的工程实现 2026/9/25 4:10:23

随机波浪速度与波浪力计算:从JONSWAP谱到Morison方程的工程实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
urql retryExchange 深度解析:重试机制、退避算法与版本演进全指南 2026/9/25 4:10:23

urql retryExchange 深度解析:重试机制、退避算法与版本演进全指南

前端 【免费下载链接】urql The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow. 项目地址: https://gitcode.com/gh_mirrors/ur/urql 点击查看 免费下载 urql/exchange-retry 是 urql Gr…

阅读更多 →
Yii 2 控制台应用实战指南:从内置命令到自定义 Command 的完整开发手册 2026/9/25 4:10:23

Yii 2 控制台应用实战指南:从内置命令到自定义 Command 的完整开发手册

后端Web框架 【免费下载链接】yii2 Yii 2: The Fast, Secure and Professional PHP Framework 项目地址: https://gitcode.com/gh_mirrors/yi/yii2 点击查看 免费下载 Yii 2 在提供完善的 Web 开发能力之外,还内置了与 Web 应用同等成熟的控制台&#x…

阅读更多 →
Simulink是什么与怎么用:安装配置、仿真建模完整指南 2026/9/25 4:10:17

Simulink是什么与怎么用:安装配置、仿真建模完整指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
大模型网关自动密钥分配:MCP+CLI一体化调用方案 2026/9/25 4:10:16

大模型网关自动密钥分配:MCP+CLI一体化调用方案

1. 项目概述:为什么你需要一个“自动分配密钥”的大模型网关调用中枢大模型网关不是个新概念,但真正把它用得顺、用得稳、用得省心的人,其实不多。我见过太多团队——前端同学在调试接口时反复粘贴 Authorization 头,后端同学手动…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉