
后端数据库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 API 打造的 GraphQL binding可看作 Prisma 服务自动生成的 SDK。它让你在编写 GraphQL 解析器resolvers时不再手写 SQL 或直接调用 MongoDB 等 NoSQL API而是将查询/变更的执行**委托delegate**给底层 Prisma 数据库服务大多数 resolver 一行即可完成。本指南完整梳理其工作原理、实操步骤、完整 API 与代码生成工具并结合仓库源码cli/packages/prisma-client-lib深入剖析底层实现帮助你在自己的 GraphQL 服务器项目中快速落地这套模式。概览prisma-binding是什么在 Prisma 时代开发者常需搭建应用层 GraphQL 服务器 Prisma 数据库服务的双层架构。应用服务器上的 resolver 负责业务逻辑而数据访问需打到 Prisma 服务暴露的 GraphQL API 上。prisma-binding正是为消除这一层样板代码而生它是面向 Prisma GraphQL API 的专用 GraphQL binding 库其角色类似Prisma 服务的自动生成 SDK通过委托执行把 resolver 中的查询/变更转交给底层 Prisma 数据库服务的 API 处理resolver 的绝大多数实现退化为一行委托调用不再需要手写 SQL 或原生数据库客户端代码。从仓库源码看prisma-binding的前身与核心实现沉淀在 prisma-client-lib 中Client类通过buildMethods()把查询、变更操作动态挂载到实例上并基于graphql-request兼容的 HTTP 客户端向 Prisma 服务发起请求。文档原文还提到两篇可参考的延伸阅读GraphQL Bindings 的复用与组合、Binding 2.0 的 API 改进与自动 codegen本仓库内对应主题可参见 GraphQL Binding 生态文档。核心示例resolver 一行委托应用层 schema假设你的 GraphQL 服务器拥有如下应用层 schemaschema.graphql# 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 }基于 Prisma binding 的 resolver 实现当Prismabinding 实例以ctx.db的形式注入到 context 后对应的 resolvers 可这样实现const 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, ) }, }, }每个 resolver 的核心都是ctx.db.query.*或ctx.db.mutation.*调用第一个参数是查询/变更所需的参数对象如where、data第二个参数info来自解析器签名表示客户端的 selection set——binding 会基于它自动构造返回字段实现字段级的数据获取无需手动拼 GraphQL 文档。该示例对应的完整教程可参考 从零构建一个 GraphQL 服务器其中展示了db: new Prisma({...})注入 context 的完整写法。五个步骤用 Prisma binding 搭建 GraphQL 服务器定义数据模型创建 Prisma 服务编写数据模型datamodel通过prisma deploy部署生成带完整 CRUD API 的 Prisma 服务下载生成的 Prisma 数据库 schema即prisma.graphql包含完整的 CRUD API定义应用层 schema通常命名为schema.graphql并# import需要的 Prisma 类型实例化Prisma传入 Prisma 服务的endpoint、数据库 schema 定义文件路径等信息实现应用层 resolvers通过生成的委托 resolver 函数把业务查询/变更委托给底层 Prisma 服务。提示若使用 GraphQL boilerplate 项目例如通过graphql create生成binding 通常已经配置好并预置了示例 resolvers。你可以体验动态 binding如node-basicboilerplate或静态 binding如typescript-basicboilerplate。实例化与注入 context 的完整示例结合仓库内教程文档Build-a-GraphQL-Server-from-ScratchPrisma实例通常在GraphQLServer的context工厂中创建const server new GraphQLServer({ typeDefs: ./src/schema.graphql, resolvers, context: req ({ ...req, db: new Prisma({ typeDefs: src/generated/prisma.graphql, // 生成的 Prisma DB schema endpoint: __PRISMA_ENDPOINT__, // Prisma DB 服务的 endpoint来自 prisma.yml secret: mysecret123, // 在 database/prisma.yml 中指定 debug: true, // 在控制台打印所有 GraphQL 查询与变更 }), }), }) server.start(() console.log(Server is running on http://localhost:4000))注意将__PRISMA_ENDPOINT__替换为prisma.yml中声明的真实 endpoint。此后所有 resolver 只需转发请求给底层 Prisma 的查询引擎即可——这正是 binding 的核心价值resolver 逻辑近乎琐碎繁重工作由 Prisma 服务完成免去了在 resolver 中手写 SQL 的噩梦。完整 API 参考基于具体服务实例化Prisma以如下数据模型为例type User { id: ID! unique name: String }实例化并执行操作// 基于具体服务实例化 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 }) // 更新指定用户的名字并返回 id prisma.mutation.updateUser({ where: { id: abc }, data: { name: Sarah } }, { id }) // 删除指定用户并返回 name prisma.mutation.deleteUser({ where: { id: abc } }, { id })实现细节在底层每个函数调用都会被翻译成一次针对 Prisma 服务的真实 HTTP 请求基于graphql-request。在仓库实现中这一过程由 Client.ts 的BatchedGraphQLClient完成构造函数将typeDefs通过buildSchema解析为GraphQLSchema随后buildMethods()依据 schema 中的Query/Mutation/Subscription类型动态生成委托方法请求时携带Authorization: Bearer token头token 由secret经jsonwebtoken签名生成。binding 还支持判断节点是否存在// 询问是否存在 id 为 abc 且 author 名为 Sarah 的 post返回布尔值 prisma.exists.Post({ id: abc, author: { name: Sarah } })constructorconstructor(options: PrismaOptions): PrismaPrismaOptions字段说明KeyRequiredTypeDefaultNoteschemaPathYesstring-Prisma 服务 schema 定义的文件路径通常为database.graphqlendpointYesstring-Prisma 服务的 endpointsecretYesstring-Prisma 服务的 secretfragmentReplacementsNoFragmentReplacementsnullGraphQL fragment 定义列表声明 resolver 正常运作所需的字段debugNobooleanfalse在控制台打印所有查询/变更仓库中的ClientOptions见 types.ts与此一一对应endpoint必填secret与debug可选typeDefs对应文档中的schemaPath另含models用于标记内嵌embedded类型。debug开启时processInstructions 会打印完整查询文档与变量。query 与 mutationquery和mutation是Prisma实例上的公开属性类型为Query暴露一组以 Prisma 数据库 schema 中Query/Mutation类型字段命名的、自动生成的委托 resolver 函数。每个委托 resolver 本质上是发送查询/变更到 Prisma 服务的便捷 API你无需从零拼写完整查询语句、也无需关心 HTTP 传输细节——这些都封装在委托函数内部。委托 resolver 的接口如下(args: any, info: GraphQLResolveInfo | string): PromiseT参数语义args携带查询/变更所需参数的对象info代表查询/变更 selection set 的对象既可以是字符串也可以是GraphQLResolveInfo类型来自 graphql-js通常直接透传 resolver 的第四个参数泛型T对应目标字段的类型。从源码看query/mutation的生成逻辑位于 Client.ts 的 buildMethods / getTypes它遍历 schema 的类型映射为每个对象类型的字段生成可链式调用的函数并通过指令队列_currentInstructions累积嵌套调用后统一构建 GraphQL 文档首个调用的参数会被智能包装——例如Mutation下create*前缀的字段自动把参数包进datadelete*前缀的字段自动包进where单参数 Query 字段则自动包进where见 Client.ts这与文档示例中createPost({ data: ... })、deletePost({ where: ... })的调用形式完全吻合。existsexists同样是Prisma实例上的公开属性。与query、mutation类似它也暴露若干自动生成的函数但每个类型只有一个函数名取自可检索单个节点对应根字段的类型名例如类型User对应User函数。它接收一个where对象作为输入返回boolean指示条件是否满足用于快速判断某类型的节点是否存在于 Prisma 数据库中。源码对应buildExists()Client.ts它读取 schema 的查询根类型收集各类型的单数/复数查询字段生成[类型名]: args 查询(...).then(res res.length 0)的布尔判断逻辑。requestrequest方法用于向 Prisma 服务发送 GraphQL 查询/变更功能与自动生成的委托 resolver 一致但需要你手动拼写完整查询语句因此更冗长。其底层同样基于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)) // 示例结果 // {data: { user: { id: abc, name: Sarah } } }对应实现为buildGraphQL()Client.ts直接通过内部 HTTP 客户端发送原始 query 与变量。代码生成Codegen生成静态类型 bindingprisma-binding内置了生成器 CLI可基于 Prisma schema 自动生成带类型信息的 binding 代码。安装使用 npmnpm install -g prisma-binding使用 yarnyarn global add prisma-binding命令行用法Usage: prisma-binding -i [input] -l [language] -b [outputBinding] Options: --help Show help [boolean] --version Show version number [boolean] --input, -i 指向 prisma.graphql 文件的路径 [string] [required] --language, -l 生成器语言可选typescript, javascript [string] [required] --outputBinding, -b 输出 binding 文件例如 binding.ts [string] [required]与 GraphQL Config 集成prisma-bindingCLI 支持 GraphQL Config不传命令行参数改为编写.graphqlconfig.yml由 CLI 读取。例如projects: myapp: schemaPath: src/generated/prisma.graphql extensions: prisma: prisma/prisma.yml codegen: - generator: prisma-binding language: typescript output: binding: src/generated/prisma.ts在存在上述.graphqlconfig的目录中执行graphql codegen等价于运行prisma-binding \ --language typescript \ --outputBinding src/generated/prisma.ts仓库中的代码生成实现可参见 typescript-client.tsTypescriptGenerator内置了Int → number、String → string、ID → string | number、DateTimeInput → Date | string等标量映射见文件开头并生成类型安全的query/mutation/$exists委托方法与Prisma接口定义。类似的JavascriptGenerator、FlowGenerator、GoGenerator也在 index.ts 中一并导出。从prisma-bindingv1.X 升级低于 2.0 的prisma-binding基于graphql prepare而非graphql codegen。升级到 2.x 后需更新项目文件prisma.yml# ... 其他属性 hooks: post-deploy: - graphql get-schema - graphql codegen.graphqlconfig.ymlprojects: myapp: schemaPath: src/generated/prisma.graphql extensions: prisma: prisma/prisma.yml codegen: - generator: prisma-binding language: typescript output: binding: src/generated/prisma.ts底层原理binding 是如何把调用变成 HTTP 请求的从源码结构看prisma-binding的核心机制可以归纳为三层Schema 驱动的动态方法生成Client构造函数用buildSchema(typeDefs)解析数据库 schemabuildMethods()据此把Query/Mutation的每个根字段注册为可调用函数并支持嵌套类型上的链式委托调用见 Client.ts。指令累积与文档构建每次调用把{ fieldName, args, field, typeName }压入_currentInstructionsprocessInstructions调用generateSelections将指令还原为 GraphQL AST并为参数自动生成变量定义若没有显式 selection set还会自动补全__typename等默认字段Client.ts。HTTP 执行与响应提取execute通过BatchedGraphQLClient发送请求extractPayload逐层解包返回数据剥离仅含__typename的占位对象Client.ts。正因如此你的 resolver 只需传递infobinding 就能精确地只请求客户端需要的字段并自动完成从链式 JS 调用到合法 GraphQL 文档的转换——这就是委托 resolver一行的全部魔力所在。总结prisma-binding把 Prisma 服务的 GraphQL API 封装成可编程的委托式 SDK应用层 resolver 通过ctx.db.query.*/ctx.db.mutation.*一行委托即可完成复杂的数据读写exists提供快捷的存在性判断request保留原始 GraphQL 的完全控制力配合内置 CLI 与 GraphQL Config还能一键生成类型安全的静态 binding。这套应用层 schema Prisma 数据库 schema 委托 resolver的开发范式正是当时基于 Prisma 构建 GraphQL 服务器的主流实践其思路也被后续的 Prisma Client 所继承。赞分享后端数据库GraphQL【免费下载链接】prisma1 Database Tools incl. ORM, Migrations and Admin UI (Postgres, MySQL MongoDB) [deprecated]项目地址https://gitcode.com/gh_mirrors/pr/prisma1点击查看免费下载相关推荐prisma-binding 完全指南基于 GraphQL Binding 构建 Prisma 服务上的 GraphQL 服务器prisma binding 完全指南基于 GraphQL Binding 构建 Prisma 服务上的 GraphQL 服务器 导读 prisma bind后端数据库GraphQLPrisma Bindings 使用指南用 prisma-binding 构建基于 Prisma 服务的 GraphQL 服务器Prisma Bindings 使用指南用 prisma binding 构建基于 Prisma 服务的 GraphQL 服务器 导读 prisma bind后端数据库GraphQLPrisma Bindings 实战指南用自动生成的 GraphQL 绑定 SDK 构建基于 Prisma 的 GraphQL 服务器Prisma Bindings 实战指南用自动生成的 GraphQL 绑定 SDK 构建基于 Prisma 的 GraphQL 服务器 prisma bind后端数据库GraphQL创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考