使用 prisma-binding 构建基于 Prisma 服务的 GraphQL 服务器

发布时间:2026/9/24 16:30:17
使用 prisma-binding 构建基于 Prisma 服务的 GraphQL 服务器
使用 prisma-binding 构建基于 Prisma 服务的 GraphQL 服务器【免费下载链接】prisma1 Database Tools incl. ORM, Migrations and Admin UI (Postgres, MySQL MongoDB) [deprecated]项目地址: https://gitcode.com/gh_mirrors/pr/prisma1导读prisma-binding是专门为 Prisma 服务设计的 GraphQL binding 实现它为在 Prisma 服务之上构建 GraphQL 服务器提供了一层便捷封装你可以把查询、变更的执行委托给底层 Prisma 数据库服务的 API而不必在 resolver 里手写 SQL 或直接调用 MongoDB 等 NoSQL API。读完本文你将掌握Prisma实例的实例化方式、query/mutation/exists/request四个核心 API 的用法以及如何用生成的 delegate resolver 函数把大多数 resolver 写成一行代码。Prisma Binding 是什么prisma-binding是一个专门面向 Prisma 服务的 GraphQL binding。它提供的是一层便捷层convenience layer用于在 Prisma 服务之上构建 GraphQL 服务器。简单来说它通过把查询或变更的执行委托给底层 Prisma 数据库服务的 API极大简化了 GraphQL resolver 的实现大多数 resolver 不再需要编写 SQL也不需要在 resolver 内部直接访问 MongoDB 这类 NoSQL 数据库 API而只是简单的单行调用。在本文档对应的 1.4 版本中Prisma Bindings 章节位于 docs/1.4/04-Reference/08-Prisma-Bindings包含 Overview 与 API 两个部分前者介绍整体思路与使用流程后者给出完整的 API 参考。核心示例把 resolver 写成一行代码假设你的 GraphQL 服务器有一个这样的应用 schemaapplication schema# import Post from ./generated/prisma.graphql type Query { posts: [Post!]! post(id: ID!): Post description: String! } type Mutation { createDraft(title: String!, text: String): Post deletePost(id: ID!): Post publish(id: ID!): Post }对应的 resolver 实现如下。注意每个 resolver 都通过ctx.db上自动生成的委托函数把实际执行委托给 Prisma 服务并将info透传下去以保证查询的选择集selection set能原样作用于底层 APIconst resolvers { Query: { posts(parent, args, ctx, info) { return ctx.db.query.posts({ }, info) }, post(parent, args, ctx, info) { return ctx.db.query.post({ where: { id: args.id } }, info) }, }, Mutation: { createDraft(parent, { title, text }, ctx, info) { return ctx.db.mutation.createPost( { data: { title, text, }, }, info, ) }, deletePost(parent, { id }, ctx, info) { return ctx.db.mutation.deletePost({ where: { id } }, info) }, publish(parent, { id }, ctx, info) { return ctx.db.mutation.updatePost( { where: { id }, data: { isPublished: true }, }, info, ) }, }, }这段代码背后对应的 Prisma 数据模型data model会生成包含完整 CRUD API 的generated/prisma.graphql即文档中提到的database.graphqlPost类型及其createPost、updatePost、deletePost、posts、post等根字段全部由 Prisma 服务的模式定义自动推导而来。你可以在 docs/1.4/04-Reference/03-Prisma-API 章节中进一步了解 Prisma 自动生成的 Query / Mutation API 形态。使用 Prisma Binding 构建服务器的五个步骤官方文档给出了使用 Prisma binding 构建 GraphQL 服务器的标准工作流创建 Prisma 服务先定义数据模型data model创建你的 Prisma service。下载生成的数据库 schema即database.graphql其中包含完整的 CRUD API生成文件通常位于generated/prisma.graphql。定义应用 schema一般命名为app.graphql描述你的 GraphQL 服务器对外暴露的 API。实例化Prisma传入关于你的 Prisma 服务的信息例如服务 endpoint 以及数据库 schema 定义文件的路径。实现 resolver为应用 schema 的各个字段实现 resolver通过生成的 delegate resolver 函数把执行委托给底层 Prisma 服务。如果你使用 GraphQL boilerplate 项目例如通过graphql create创建Prisma binding 通常已经预先配置好并为你实现了一部分示例 resolver。示例工程会区分两种绑定形态动态绑定dynamic binding如node-basicboilerplate与静态绑定static binding如typescript-basicboilerplate后者配合代码生成能获得更强的类型安全。安装在 Node.js 项目中使用 yarn 或 npm 安装yarn add prisma-binding # or npm install --save prisma-bindingAPI 参考实例化与基础 CRUD考虑如下的 Prisma 服务数据模型type User { id: ID! unique name: String }基于该服务实例化Prisma之后就可以发送以下查询/变更// 基于具体的服务实例化 Prisma const prisma new Prisma({ typeDefs: schemas/database.graphql, endpoint: https://api.graph.cool/simple/v1/my-prisma-service secret: my-super-secret-secret }) // 查询某个用户的 name prisma.query.user({ where { id: abc } }, { name }) // 查询所有用户的 id 和 name prisma.query.users(null, { id name }) // 创建名为 Sarah 的用户并返回 id prisma.mutation.createUser({ data: { name: Sarah } }, { id }) // 更新某个用户的 name 为 Sarah 并返回 id prisma.mutation.updateUser({ where: { id: abc }, data: { name: Sarah } }, { id }) // 删除某个用户并返回 id prisma.mutation.deleteUser({ where: { id: abc } }, { id })在底层这些函数调用中的每一个都会被翻译成一次针对你的 Prisma 服务的真实 HTTP 请求通过graphql-request实现你无需手动拼写完整的查询字符串也不必关心 HTTP 传输细节——这些全部由 delegate resolver 函数在内部处理。API 还支持询问某个节点是否存在于 Prisma 数据库中// 询问是否存在一个 id 为 abc 的 post // 且其 author 名为 Sarah返回布尔值 prisma.exists.Post({ id: abc, author: { name: Sarah } })constructor 与 PrismaOptions构造函数签名如下constructor(options: PrismaOptions): PrismaPrismaOptions类型的字段如下表所示KeyRequiredTypeDefaultNoteschemaPathYesstring-你的 Prisma 服务 schema 定义的文件路径通常是一个名为database.graphql的文件endpointYesstring-你的 Prisma 服务的 endpointsecretYesstring-你的 Prisma 服务的 secretfragmentReplacementsNoFragmentReplacementsnull一组 GraphQL fragment 定义指定 resolver 正常工作所需的字段debugNobooleanfalse将所有的查询/变更打印到控制台其中fragmentReplacements是一个值得留意的选项当你的 resolver 依赖某些嵌套字段例如关系字段的子选择时可以通过 fragment 把这些必需字段注入到底层查询中确保委托执行时不会遗漏。debug则用于排查问题——打开后所有发往 Prisma 服务的查询/变更都会输出到控制台便于观察实际发送的 GraphQL 语句。query 与 mutationquery和mutation是Prisma实例上的两个公开属性。它们的类型均为Query暴露一组自动生成的 delegate resolver 函数函数命名与 Prisma 数据库 schema 中Query和Mutation类型上的字段一一对应例如上面的users、user、createUser、updateUser、deleteUser。每个 delegate resolver 本质上都是一个便捷 API你无需从头拼写完整的查询/变更也不用操心通过 HTTP 发送的问题这一切都在 delegate resolver 函数内部处理完毕。delegate resolver 的接口如下(args: any, info: GraphQLResolveInfo | string): PromiseT参数的使用方式args携带查询/变更潜在参数的对象info表示查询/变更选择集的对象既可以直接用字符串表达如{ id name }也可以用GraphQLResolveInfo形式传入在 resolver 中通常直接透传来自 GraphQL 执行层的info。泛型类型T对应各自字段的类型。existsexists同样是Prisma实例上的公开属性。与query、mutation类似它也暴露一组自动生成的函数但每个类型只对应一个函数。函数命名遵循能检索该类型单个节点的根字段的规则例如类型User对应User函数。它接收一个where对象作为输入返回一个boolean值表示where表达的条件是否被满足。该函数让你能够方便地检查 Prisma 数据库中是否存在某个特定类型的节点——例如在权限校验、防重复创建等场景中非常实用。requestrequest方法允许你直接向 Prisma 服务发送 GraphQL 查询/变更。其功能与自动生成的 delegate resolver 相同但 API 更加冗长——因为你需要自己拼写完整的查询/变更。request底层同样使用graphql-request实现。使用示例const query query ($userId: ID!){ user(id: $userId) { id name } } const variables { userId: abc } prisma.request(query, variables) .then(result console.log(result)) // sample result: // {data: { user: { id: abc, name: Sarah } } }可以看到request适合需要完全掌控查询文本的场景例如动态拼接查询、批量执行等而日常的 resolver 委托则优先使用自动生成的 delegate resolver。从文档结构与版本演进看 Prisma Binding在仓库中Prisma Bindings 是 Prisma 参考文档04-Reference的固定章节从 docs/1.4/04-Reference/08-Prisma-Bindings 到 docs/1.10/04-Reference/08-Prisma-Bindings 均有完整章节同时 docs/1.0/06-GraphQL-Ecosystem/02-GraphQL-Binding 从 GraphQL 生态视角介绍了 binding 的一般思想与 Prisma binding 的定位。由此可以看出Prisma binding 是官方推荐的在 Prisma 之上构建 GraphQL 服务器的核心手段与 docs/1.4/04-Reference/03-Prisma-API 中描述的自动生成 API 紧密配合。在后续版本1.10 及之后中prisma-binding还演进出了代码生成codegen能力通过内置的生成器 CLI可以把prisma.graphql生成静态类型的 binding 文件TypeScript / JavaScript并可与 GraphQL Config 集成——在.graphqlconfig.yml的extensions.codegen中声明generator: prisma-binding与language: typescript之后只需执行graphql codegen即可完成生成详见 docs/1.10/04-Reference/08-Prisma-Bindings/03-Code-generation.md。这种静态绑定方案正是typescript-basicboilerplate 所采用的形态。小结prisma-binding通过委托执行的设计把 Prisma 自动生成的数据库 CRUD API 包装成可编程、可组合的 delegate resolver 函数Prisma实例化只需schemaPath、endpoint、secret三个必要参数另可选用fragmentReplacements与debugquery/mutation暴露按字段自动生成的委托函数配合args info的接口即可在 resolver 中透传选择集exists提供按类型的存在性判断request提供完全自定义的查询发送能力结合后续版本引入的 codegen还可以进一步生成类型安全的静态 binding。对于想要快速在 Prisma 服务之上搭建业务 GraphQL 层的开发者这一层封装能够显著减少样板代码让 resolver 保持简洁、可读且易于维护。【免费下载链接】prisma1 Database Tools incl. ORM, Migrations and Admin UI (Postgres, MySQL MongoDB) [deprecated]项目地址: https://gitcode.com/gh_mirrors/pr/prisma1创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考