ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

使用 Prisma Bindings 从 Node 脚本访问 Prisma 服务

使用 Prisma Bindings 从 Node 脚本访问 Prisma 服务 后端数据库GraphQL【免费下载链接】prisma1 Database Tools incl. ORM, Migrations and Admin UI (Postgres, MySQL MongoDB) [deprecated]项目地址https://gitcode.com/gh_mirrors/pr/prisma1点击查看免费下载本教程面向已拥有运行中 Prisma 服务的开发者讲解如何在一个轻量 Node 脚本中通过prisma-binding生成的类型化 API即Prisma bindings完成对 Prisma 服务的查询query、变更mutation与存在性检查exists等操作。读完本文你将掌握从数据模型更新、项目目录搭建、GraphQL schema 下载到编写并运行可复用的 Node 访问脚本的完整链路并能理解 Prisma binding 底层如何基于 GraphQL schema 动态生成调用接口。准备工作你需要一个运行中的 Prisma 服务本教程假设你已拥有一个可访问的 Prisma 服务因此开始之前请确保手里有该服务的endpoint端点地址。如果你还不清楚如何快速搭建自己的 Prisma 服务可以参考仓库中以下教程对应docs/1.13/03-Tutorials2/01-Setup-Prisma目录在 Demo server 上设置 Prisma使用 Prisma Cloud 托管的免费演示环境适合学习、原型与开发但存在限流与存储上限不建议用于生产。使用新的 MySQL 数据库设置 Prisma使用新的 Postgres 数据库设置 Prisma连接你自己的空 MySQL 数据库设置 Prisma连接你自己的空 Postgres 数据库设置 Prisma提示教程中的每一步操作都带有编号标记避免遗漏如果你只关心操作步骤本身可以直接按指令逐步执行。Step 1更新数据模型首先确保你的 Prisma 服务具有本教程后续步骤所需的数据模型。本教程假定你的数据模型存放在单一文件datamodel.graphql中如果实际布局不同请相应调整。操作 1打开datamodel.graphql将其内容更新为type User { id: ID! unique name: String! posts: [Post!]! } type Post { id: ID! unique title: String! content: String! published: Boolean! default(value: false) author: User! }操作 2保存文件后打开终端并进入 Prisma 服务根目录即prisma.yml所在目录运行以下命令更新其 GraphQL APIprisma deploy更新后Prisma 服务的 GraphQL API 将为User与Post两种类型暴露完整的 CRUD 操作同时允许你修改二者之间的关系relation一个User拥有多条Postposts: [Post!]!每条Post又必须归属一个Userauthor: User!。从源码看prisma deploy之后发生了什么prisma deploy会依据prisma.yml中的配置将数据模型同步到 Prisma 服务并重新生成对应的 GraphQL API。这里值得一提的细节是default(value: false)指令——它让published字段在创建Post时自动获得默认值false因此后续脚本创建文章时无需显式传入该字段。这一点在 Step 4 的示例输出中可以直接看到createPost返回的对象里published: false正是默认值起作用的证据。Step 2设置项目目录结构数据模型更新完成后开始搭建脚本项目。操作 1进入一个新目录在终端中依次执行mkdir -p my-node-script/src touch my-node-script/src/index.js cd my-node-script yarn init -y操作 2接下来把 Prisma 服务根目录移入my-node-script并重命名为prismacd .. mkdir my-node-script/prisma mv datamodel.graphql prisma.yml my-node-script/prisma cd my-node-script此时项目结构应如下所示. └── my-node-script ├── package.json ├── prisma │ ├── datamodel.graphql │ └── prisma.yml └── src └── index.js操作 3安装prisma-binding及 GraphQL 核心库yarn add prisma-binding graphqlprisma-binding是本教程的主角——它是从 Prisma schema 生成类型化 JavaScript API 的运行时库graphql则提供底层 schema 解析与文档构建能力。从本仓库的 prisma-client-lib 包 源码可以看到Prisma绑定实例在构造时会调用buildSchema(typeDefs)解析传入的 schema并通过BatchedGraphQLClient与SubscriptionClient分别建立查询/变更与订阅通道这正是绑定实例 面向 Prisma 服务的 JavaScript SDK这一说法的实现基础。Step 3下载 Prisma database schema下一步是把 Prisma GraphQL API 的 schema即Prisma database schema下载到本地项目供 Prisma binding 指向使用。该操作借助 GraphQL CLI 与 GraphQL Config 完成。操作 1全局安装 GraphQL CLIyarn global add graphql-cli操作 2在my-node-script目录服务根目录创建.graphqlconfig.ymltouch .graphqlconfig.yml操作 3向其中写入以下内容把 Prisma 的 GraphQL API 定义为一个projectprojects: prisma: schemaPath: src/generated/prisma.graphql extensions: prisma: prisma/prisma.yml此文件提供的信息会被 GraphQL CLI 以及 GraphQL Playground 共同使用schemaPath指定下载后 schema 的落盘位置extensions.prisma则指向你的prisma.yml让 CLI 知道从哪里读取 endpoint 等连接信息。操作 4运行以下命令将 Prisma database schema 下载到src/generated/prisma.graphqlgraphql get-schema下载完成后定义了你数据库完整 CRUD API 的 Prisma database schema 就位于projects.prisma.schemaPath属性指定的位置即src/generated/prisma.graphql。Pro tip如果你希望每次部署例如更新数据模型后 schema 都自动刷新可以在prisma.yml中添加如下post-deployment hook。hooks是prisma.yml中可选的配置项用于在 Prisma CLI 特定动作前后执行终端命令当前可用的是post-deploy在prisma deploy之后触发其类型为对象键名与可用钩子一一对应。更完整的说明见 prisma.yml 配置参考hooks: post-deploy: - graphql get-schema -p prisma仓库中 YAML-Structure.md 还给出了post-deploy同时执行多个任务的示例例如打印部署完成信息、为dbproject 下载 schema、执行代码生成等读者可自行参考扩展。Step 4使用 Prisma binding 发送查询与变更本步骤将正式使用 Prisma binding 与你的 Prisma 服务通信。首先通过指向上一步下载的 schema 来实例化一个 Prisma binding由于绑定实例需要连接到你的 Prisma API因此还必须提供 Prisma API 的endpoint该值可从prisma/prisma.yml中查到。绑定实例充当 Prisma 服务的JavaScript SDK你可以调用其 API 向 Prisma 数据库发送查询与变更。操作 1将以下代码写入src/index.js。它创建了一个Prisma绑定实例并依次执行创建用户、查询用户、创建文章、更新文章、级联查询以及批量删除等操作⚠️Important务必把__YOUR_PRISMA_ENDPOINT__替换为你的 Prisma endpoint它存储在prisma/prisma.yml中。const { Prisma } require(prisma-binding) const prisma new Prisma({ typeDefs: src/generated/prisma.graphql, endpoint: __YOUR_PRISMA_ENDPOINT__ }) prisma.mutation .createUser({ data: { name: Alice } }, { id name }) .then(console.log) // { id: cjhcidn31c88i0b62zp4tdemt, name: Alice } .then(() prisma.query.users(null, { id name })) .then(response { console.log(response) // [ { id: cjhcidn31c88i0b62zp4tdemt, name: Alice } ] return prisma.mutation.createPost({ data: { title: Prisma rocks!, content: Prisma rocks!, author: { connect: { id: response[0].id } } } }) }) .then(response { console.log(response) /* { id: cjhcidoo5c8af0b62kv4dtv3c, title: Prisma rocks!, content: Prisma rocks!, published: false } */ return prisma.mutation.updatePost({ where: { id: response.id }, data: { published: true } }) }) .then(console.log) /* { id: cjhcidoo5c8af0b62kv4dtv3c, title: Prisma rocks!, content: Prisma rocks!, published: true } */ .then(() prisma.query.users(null, { id posts { title } })) .then(console.log) // [ { id: cjhcidn31c88i0b62zp4tdemt, posts: [ [Object] ] } ] .then(() prisma.mutation.deleteManyPosts()) .then(console.log) // { count: 1 } .then(() prisma.mutation.deleteManyUsers()) .then(console.log) // { count: 1 }操作 2运行脚本观察终端打印的查询结果node src/index.js理解绑定 API 的调用约定从代码可以看出 Prisma binding 的两个关键调用形态query/mutation每个数据模型类型对应一组方法例如users、createUser、updatePost、deleteManyPosts。方法签名通常为(args, selectionSet)——第一个参数是 GraphQL 变量如data、where第二个参数是你想要返回的字段选择集如{ id name }。绑定实例在内部会基于下载的 schema 解析出对应字段与类型动态生成 GraphQL 文档后发送请求。关系写入创建文章时通过author: { connect: { id: ... } }关联已存在的User这是 Prisma 处理关系型嵌套写入的标准语法——connect表示连接到已有节点而create则表示同时新建关联节点。从 Client.ts 的实现看query、mutation、$subscribe、$graphql、$exists等属性均在构造阶段通过buildMethods()等内部方法构建每个调用先记录为一组 instructions再经getDocumentForInstructions生成完整 GraphQL 文档并交由底层的BatchedGraphQLClient发送同时它支持通过secret配置签发 JWT 令牌以Authorization: Bearer token请求头完成鉴权。也就是说你使用的类型化 SDK本质上是基于 schema 动态生成的、对 GraphQL 请求的封装层。Step 5使用exists检查特定节点的存在性除了query和mutationPrisma binding 还提供了一个便捷属性exists用于检查数据库中是否存在满足特定条件的节点。exists为数据模型中的每个类型暴露一个函数函数名与类型同名本例即prisma.exists.User(filter)和prisma.exists.Post(filter)。这些函数接收filter参数始终返回true或false。因为Step 1创建的数据模型包含User与Post两个模型Prisma 便生成了exists.User与exists.Post。操作 1将以下代码写入src/index.js。它实例化 Prisma binding创建用户与文章后使用exists验证节点存在性删除数据后再验证节点已不存在⚠️Important务必把__YOUR_PRISMA_ENDPOINT__替换为你的 Prisma endpoint它存储在prisma/prisma.yml中。const { Prisma } require(prisma-binding) const prisma new Prisma({ typeDefs: src/generated/prisma.graphql, endpoint: __YOUR_PRISMA_ENDPOINT__ }) prisma.mutation .createUser({ data: { name: Alice } }, { id name }) .then(response { return prisma.mutation.createPost({ data: { title: Prisma rocks!, content: Prisma rocks!, author: { connect: { id: response.id } } } }) }) .then(() prisma.exists.User({ name: Alice })) .then(response console.log(response)) // true .then(() prisma.exists.Post({ title: Prisma rocks })) .then(response console.log(response)) // true .then(() prisma.mutation.deleteManyPosts()) .then(() prisma.mutation.deleteManyUsers()) .then(() prisma.exists.Post({ title: Prisma rocks })) .then(response console.log(response)) // false .then(() prisma.exists.User({ name: Alice })) .then(console.log) // false操作 2运行脚本观察终端打印的结果node src/index.jsexists的典型用途exists非常适合在写入前做幂等校验或条件判断例如用户名是否已注册文章标题是否已存在这类场景。它避免了手写完整的users(where: ...)查询再自行判空的样板代码返回值语义清晰布尔值可直接用于业务分支。在仓库的 Client.ts 中$exists由buildExists()构建内部同样基于 schema 中每个类型的where过滤参数生成对应查询其实现与query/mutation共享同一套指令与文档生成管线。Step 6以字符串形式发送原始查询与变更Prisma binding 还允许你通过request属性把完整的查询/变更以字符串形式直接发给 Prisma 服务。这种方式更为冗长——你需要拼写完整操作且响应会多一层开销因为返回结果会以查询/变更的名称作为顶层 key 包裹。说明Prisma binding 的request底层使用graphql-request因此与它拥有相同的 API 形态即request(query, variables?)。操作 1将src/index.js的内容替换为以下代码⚠️Important务必把__YOUR_PRISMA_ENDPOINT__替换为你的 Prisma endpoint它存储在prisma/prisma.yml中。const { Prisma } require(prisma-binding) const prisma new Prisma({ typeDefs: src/generated/prisma.graphql, endpoint: __YOUR_PRISMA_ENDPOINT__ }) const query { users { id name } } const mutation mutation CreateUser($name: String!) { createUser(data: { name: $name }) { id name } } const variables { name: Bob } prisma.mutation .createUser({ data: { name: Alice } }, { id name }) .then(console.log) // { id: cjhcijh30cgww0b622rwkkvbo, name: Alice } .then(() prisma.request(mutation, variables)) .then(console.log) // { createUser: { id: cjhcijjndch0d0b62qux6o52a, name: Bob } } .then(() prisma.query.users(null, { id name })) .then(console.log) /* [ { id: cjhciiacxcf850b62mcuaa3uz, name: Alice }, { id: cjhcijjndch0d0b62qux6o52a, name: Bob } ] */ .then(() prisma.request(query)) .then(console.log) /* { users: [ { id: cjhciiacxcf850b62mcuaa3uz, name: Alice }, { id: cjhcijjndch0d0b62qux6o52a, name: Bob } ] } */操作 2运行脚本观察终端打印的结果node src/index.js对比request与类型化 API对比 Step 4 与 Step 6 的输出可以清晰看到差异类型化调用prisma.query.users、prisma.mutation.createUser返回的是字段选择集直接对应的结果结构扁平、无需关心操作名。原始request调用则需要手写完整 GraphQL 文档可含变量定义与操作名其响应以操作名作为顶层 key如{ createUser: {...} }、{ users: [...] }并且需要自行把变量作为第二个参数传入。因此request更适合有现成 GraphQL 字符串/文档或需要动态拼接操作的场景而类型化 API 在开发体验与代码可读性上更胜一筹。小结本教程带你走完了用 Node 脚本访问 Prisma 服务的完整流程更新数据模型datamodel.graphqlprisma deploy让 Prisma 服务暴露User/Post的 CRUD API搭建项目结构将 Prisma 服务目录迁入脚本项目安装prisma-binding与graphql下载 Prisma database schema.graphqlconfig.ymlgraphql get-schema并可选配置post-deployhook 实现自动刷新类型化调用prisma.query/prisma.mutation完成增删改查与关系连接存在性检查prisma.exists.User(...)/prisma.exists.Post(...)以布尔值快速判断节点是否存在原始请求prisma.request(query, variables)以字符串形式发送完整 GraphQL 文档。这套能力可以无缝嵌入定时任务、数据迁移脚本、CI 校验、批量数据处理等场景让 Node 脚本成为 Prisma 数据库的一等公民。对绑定实例内部机制感兴趣的读者可继续阅读本仓库 prisma-client-lib 包 的源码深入理解 schema 解析、指令生成与请求批处理的具体实现。赞分享后端数据库GraphQL【免费下载链接】prisma1 Database Tools incl. ORM, Migrations and Admin UI (Postgres, MySQL MongoDB) [deprecated]项目地址https://gitcode.com/gh_mirrors/pr/prisma1点击查看免费下载相关推荐使用 Prisma Bindings 从 Node 脚本访问 Prisma 服务完整实战教程使用 Prisma Bindings 从 Node 脚本访问 Prisma 服务完整实战教程 本教程基于 Prisma 1.x 的官方操作手册完整演示如何从后端数据库GraphQL使用 Prisma Bindings 在 Node 脚本中访问 Prisma 服务完整实操指南使用 Prisma Bindings 在 Node 脚本中访问 Prisma 服务完整实操指南 本指南面向已经部署好 Prisma 服务的开发者讲解如何从零后端数据库GraphQL在 Node 脚本中通过 Prisma Bindings 访问 Prisma 服务从零搭建可运行的查询与变更客户端在 Node 脚本中通过 Prisma Bindings 访问 Prisma 服务从零搭建可运行的查询与变更客户端 本篇技术指南讲解如何在一个普通 Node.后端数据库GraphQL创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表