Prisma 服务端订阅(Server-side Subscriptions)实战指南:基于 prisma.yml 配置 Webhook 事件投递
后端数据库GraphQL【免费下载链接】prisma1 Database Tools incl. ORM, Migrations and Admin UI (Postgres, MySQL MongoDB) [deprecated]项目地址https://gitcode.com/gh_mirrors/pr/prisma1点击查看免费下载导读服务端订阅Server-side Subscriptions是 Prisma 在 GraphQL 订阅能力之外提供的事件通知机制它复用 GraphQL 订阅的查询语法与过滤能力但通过Webhook将数据变更事件投递给外部业务系统天然适配现代 Serverless 基础设施。本文以 docs/1.3/04-Reference/04-Server_side-Subscriptions/01-Overview.md 为核心骨架结合仓库内 API 服务器、Worker 服务器与共享模型的源码实现系统讲解服务端订阅的配置方法、事件投递链路与订阅查询语法读完即可在自己的 Prisma 服务中落地数据变更 → HTTP 回调的完整方案。服务端订阅是什么服务端订阅与普通的 GraphQL 订阅见 GraphQL API 参考在能力上是等价的它们共享同一套 API例如同样支持在where中提供过滤条件从而只接收你感兴趣的事件。两者的核心差异在于投递机制delivery mechanism普通 GraphQL 订阅客户端建立持久连接WebSocketPrisma 在数据变更发生时把事件实时推送到客户端。服务端订阅当服务端订阅被配置好后Prisma 会持续监控数据变更并在匹配时执行与之关联的查询——这一点与普通 GraphQL 订阅一致——但事件的消费方不再是连接的客户端而是你配置的外部端点。从源码看服务端订阅被建模为一等公民的函数类型。在 server/shared-models/src/main/scala/com/prisma/shared/models/Functions.scala 中FunctionType枚举定义了ServerSideSubscription值对应的ServerSideSubscriptionFunction同时持有name、isActive、delivery和query四个字段其中delivery当前只有一种实现——WebhookDelivery包含url与headerscase class ServerSideSubscriptionFunction( name: String, isActive: Boolean, delivery: FunctionDelivery, query: String ) extends Function sealed trait FunctionDelivery { def typeCode: FunctionDeliveryType.Value } object FunctionDeliveryType extends Enumeration { val WebhookDelivery Value(webhook-delivery) } case class WebhookDelivery( url: String, headers: Vector[(String, String)] ) extends FunctionDelivery这印证了文档中的描述当前 Prisma 通过 Webhook 投递服务端订阅事件同时按照 01-Overview.md 的说明未来计划补充直接调用 AWS Lambda 以及不同的队列queue实现。服务端订阅正是为与现代 Serverless 基础设施协同工作而设计的你无需维护常驻的订阅连接只需暴露一个 HTTP 端点接收回调。事件投递链路从 Mutation 到 Webhook理解服务端订阅最好的方式是追踪一次数据变更如何最终变成一次 HTTP 请求。结合仓库源码完整链路如下变更进入 API 服务器客户端执行一次 GraphQL mutation例如updateUser。生成副作用动作API 服务器将 mutation 解析为内部的动作序列其中与服务端订阅相关的动作是ExecuteServerSideSubscription。在 server/servers/api/src/main/scala/com/prisma/api/mutactions/SideEffectMutactionExecutor.scala 中SideEffectMutactionExecutorImpl.execute按类型分发def execute(mutaction: SideEffectMutaction): Future[Unit] mutaction match { case mutaction: PublishSubscriptionEvent PublishSubscriptionEventExecutor.execute(mutaction, apiDependencies.sssEventsPubSub) case mutaction: ExecuteServerSideSubscription ServerSideSubscriptionExecutor.execute(mutaction) }执行订阅查询并构造 WebhookServerSideSubscriptionExecutor.deliverWebhook调用SubscriptionExecutor.execute以skipPermissionCheck true、alwaysQueryMasterDatabase true的方式执行订阅函数中配置的查询只有当返回结果包含data键即事件确实匹配了过滤条件时才构造一个Webhook并发布到webhookPublishersubscriptionResult.map { case Some(json) if json.as[JsObject].keys.contains(data) val webhook Webhook( projectId project.id, functionName function.name, requestId requestId, url webhookDelivery.url, payload json.toString, id requestId, headers webhookDelivery.headers.toMap ) apiDependencies.webhookPublisher.publish(webhook) case _ () }Worker 服务器投递投递动作最终落到 server/servers/workers/src/main/scala/com/prisma/workers/WebhookDelivererWorker.scala。该 Worker 从消息总线队列消费Webhook使用SimpleHttpClient.post以Content-Type: application/json向配置的url发送POST请求并把配置的 headers 一并带上httpClient .post(wh.url, wh.payload, ContentTypes.application/json, wh.headers.toList) .recover { ... }注意其中的注释// Current decision: Do not retry delivery, treat all return codes as work item success ( ack).——从源码看当前实现不对投递失败进行重试所有返回码都被视为工作项成功即确认消费失败仅在日志中输出。如果你在真实环境使用该版本的服务端订阅应基于这个前提设计你自己的重试与告警策略。Webhook数据结构定义在 server/servers/api/src/main/scala/com/prisma/subscriptions/Webhook.scala包含projectId、functionName、requestId、url、payload、id、headers等字段方便在消息总线中流转与追踪。在 prisma.yml 中配置服务端订阅服务端订阅通过在服务配置文件prisma.yml中添加subscriptions属性来完成配置。subscriptions是一个映射map每个键对应一个订阅函数的名称其值描述该订阅的投递方式当前为webhook与订阅查询query。完整配置示例下面是 01-Overview.md 中给出的完整示例它定义了一个名为userChangedEmail的服务端订阅当任意user节点被更新时向http://example.org/sendSlackMessage发送一个包含用户name与email的 Webhook 请求该示例的语义是用户改了邮箱后向 Slack 发送消息service: my-service stage: ${env:PRISMA_STAGE} secret: ${env:PRISMA_SECRET} cluster: ${env:PRISMA_CLUSTER} datamodel: database/datamodel.graphql subscriptions: userChangedEmail: webhook: url: http://example.org/sendSlackMessage headers: Content-Type: application/json Authorization: Bearer cha2eiheiphesash3shoofo7eceexaequeebuyaequ1reishiujuu6weisao7ohc query: | subscription { user(where: { mutation_in: [UPDATED] }) { node { name email } } }配置项说明对照上面的示例与源码模型各配置项的作用如下配置层级配置项说明subscriptions.name订阅函数名如userChangedEmail对应源码中ServerSideSubscriptionFunction.name用于在日志与投递链路中标识该函数Webhook 中的functionName字段。name.webhook.urlWebhook 目标地址数据变更匹配时Prisma 将向该 URL 发送POST请求对应WebhookDelivery.url最终出现在Webhook.url字段。name.webhook.headers自定义请求头键值对形式的 HTTP 头例如Content-Type: application/json、Authorization: Bearer token对应WebhookDelivery.headers向量化的键值对投递时原样附加到请求上。生产环境建议用环境变量注入敏感令牌而不是硬编码在配置文件中。name.query订阅查询一段 GraphQLsubscription查询决定监听哪类变更、过滤哪些节点、返回哪些字段。对应ServerSideSubscriptionFunction.query由SubscriptionExecutor.execute在每次变更时执行。prisma.yml 的全局结构与env:变量引用等细节可参考 服务配置参考 目录下的文档。订阅查询语法要点订阅查询使用标准 GraphQLsubscription语法其过滤能力与普通 GraphQL 订阅一致重点包括mutation_in指定要监听哪类变更可选值为CREATED、UPDATED、DELETED。示例中mutation_in: [UPDATED]表示只对更新事件感兴趣如需监听多种类型可写成mutation_in: [CREATED, UPDATED, DELETED]。node对变更节点自身的字段做过滤仅当节点满足条件时才触发投递。测试代码中出现了node: { status: ACTIVE }、node: { text: test }之类的用法见 EmbeddedServerSideSubscriptionSpec.scala。previousValues在node之外还可以请求变更前的字段值例如previousValues { title }便于你的回调逻辑做前后对比如检测邮箱是否真的变了。node与previousValues字段选择器在node中列出你希望随 Webhook 回调携带的字段例如name、email以及关联嵌套字段。这些过滤与字段选择能力在订阅解析器 server/servers/subscriptions/src/main/scala/com/prisma/subscriptions/resolving/SubscriptionResolver.scala 及其配套的SubscriptionsManager、DatabaseEvents等组件中实现与普通 GraphQL 订阅共用同一套解析与过滤管线因此文档中的等价于普通 GraphQL 订阅在实现层面也是成立的。触发示例一次 updateUser Mutation配置好userChangedEmail之后只要客户端执行下面这样的 mutation把某个用户的email改为新地址服务端订阅就会被触发Prisma 会执行配置中的订阅查询并把匹配结果通过 Webhook 发送到http://example.org/sendSlackMessagemutation { updateUser( data: { email: newemail.com }, where: { id: cjcgo976g5twb018740bzyy4q } ) { id } }因为订阅查询中的mutation_in: [UPDATED]只关心更新事件且该 mutation 恰好是UPDATED类型并匹配user模型所以事件会被投递若执行的是创建或删除该用户的 mutation则不会触发该订阅。测试与验证仓库中为该机制提供了完整的集成测试可作为你理解行为与自行验证的参照EmbeddedServerSideSubscriptionSpec.scala针对嵌入式类型embedded的端到端测试覆盖了mutation_in、node过滤、previousValues、嵌套字段选择以及 Webhook 发布等场景。NonEmbeddedServerSideSubscriptionSpec.scala非嵌入式模型下的对应测试。WebhookDelivererWorkerSpec.scala验证 Worker 对 Webhook 的实际 HTTP 投递行为含失败日志格式。测试通过注入的webhookPublisher见webhookTestKit testDependencies.webhookPublisher断言 Webhook 是否被正确发布这与上文投递链路中apiDependencies.webhookPublisher.publish(webhook)的实现一一对应是验证配置 → 变更 → Webhook闭环最直接的证据。适用前提与限制基于当前仓库对应 Prisma 1.x 文档体系的代码实现使用服务端订阅时有几点需要明确投递方式目前仅支持 WebhookAWS Lambda 直连与队列投递是规划中的能力见 01-Overview.md 原文当前版本请以 Webhook 为准。投递不自动重试从 WebhookDelivererWorker.scala 的注释与实现看失败投递不会重试且所有返回码都会被确认请在你的回调端点做好幂等与日志记录。订阅查询的过滤能力与普通 GraphQL 订阅一致mutation_in、node、previousValues等语法均可直接使用配置时不要忘记在query中用|块语法书写多行查询字符串。本文涉及的prisma.yml、datamodel 等概念可参见 服务配置参考 与 Prisma API 参考。至此你已经掌握了 Prisma 服务端订阅的完整图景从 prisma.yml 中的一段配置到 mutation 触发的过滤查询再到 Webhook 投递的源码链路足以独立构建数据变更驱动外部系统的集成方案。赞分享后端数据库GraphQL【免费下载链接】prisma1 Database Tools incl. ORM, Migrations and Admin UI (Postgres, MySQL MongoDB) [deprecated]项目地址https://gitcode.com/gh_mirrors/pr/prisma1点击查看免费下载相关推荐Prisma 服务端订阅Server-side Subscriptions指南基于 Webhook 的事件投递机制与 prisma.yml 配置实战Prisma 服务端订阅Server side Subscriptions指南基于 Webhook 的事件投递机制与 prisma.yml 配置实战 Pr后端数据库GraphQLPrisma 服务端订阅Server-side Subscriptions实战指南在 prisma.yml 中配置 Webhook 事件订阅Prisma 服务端订阅Server side Subscriptions实战指南在 prisma.yml 中配置 Webhook 事件订阅 Prisma后端数据库GraphQLdarktable 入门7 步走完一张 RAW 的免费处理全流程darktable 入门7 步走完一张 RAW 的免费处理全流程 darktable 是一款开源的摄影工作流应用与 RAW 开发者它负责从文件管理、RAW后端数据库GraphQL上一篇构建专业级气象数据服务Open-Meteo开源平台核心技术解析与实战部署下一篇Node.js 23.3.0 (Current) 发布说明精读特性变更、完整提交与 nodejs.org 仓库如何自动生成和渲染该发布文章创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

algorithm-base 算法图解:剑指 Offer 52 与 LeetCode 160 两个链表的第一个公共节点(相交链表)双指针与哈希解法全解析

algorithm-base 算法图解:剑指 Offer 52 与 LeetCode 160 两个链表的第一个公共节点(相交链表)双指针与哈希解法全解析

文档教程知识库 【免费下载链接】algorithm-base 一位酷爱做饭的程序员,立志用动画将算法说的通俗易懂。我的面试网站 www.chengxuchu.com 项目地址: https://gitcode.com/gh_mirrors/al/algorithm-base 点击查看 免费下载 本篇基于 algorithm-base 仓库…

2026/9/24 16:16:23 阅读更多 →
C++ SFINAE从入门到放弃?不,C++20 Concepts让你10分钟学会模板约束

C++ SFINAE从入门到放弃?不,C++20 Concepts让你10分钟学会模板约束

C SFINAE从入门到放弃?不,C20 Concepts让你10分钟学会模板约束 摘要:本文用“同一个需求,三种写法”的方式,讲透C模板约束的演进——从SFINAE的“替换失败并非错误”原理,到std::enable_if的实战用法&#…

2026/9/24 16:15:22 阅读更多 →
Skia 官方文档站 Markdown 写作指南:基于 Hugo 与 Docsy 的内容组织、Frontmatter 与渲染特性详解

Skia 官方文档站 Markdown 写作指南:基于 Hugo 与 Docsy 的内容组织、Frontmatter 与渲染特性详解

图形学 【免费下载链接】skia Skia is a complete 2D graphic library for drawing Text, Geometries, and Images. See documentation for contribution instructions. 项目地址: https://gitcode.com/gh_mirrors/ski/skia 点击查看 免费下载 导读 本文是 Skia 官…

2026/9/24 16:15:22 阅读更多 →

最新新闻

vscode-copilot-chat 中的 Visualization Runner:为 `[visualizable]` 测试一键接入 VS Code 可视化调试

vscode-copilot-chat 中的 Visualization Runner:为 `[visualizable]` 测试一键接入 VS Code 可视化调试

人工智能AI 应用AI Agent代码智能体交互助手工具调用MCP Clients 【免费下载链接】vscode-copilot-chat Copilot Chat extension for VS Code 项目地址: https://gitcode.com/gh_mirrors/vs/vscode-copilot-chat 点击查看 免费下载 在微软官方 Copilot Chat 扩展仓…

2026/9/24 18:31:17 阅读更多 →
Java清城电商平台:SSM毕设项目从源码到答辩实战指南

Java清城电商平台:SSM毕设项目从源码到答辩实战指南

收到,像这种标着“最新原创毕设”的电商项目资料,我帮不少学生看过代码、调过环境。核心结论先说:免费拿到源码不是重点,重点是你拿到手之后能不能在三天之内把它吃透,然后在答辩现场用自己的话把整个购物流程讲清楚。…

2026/9/24 18:31:16 阅读更多 →
智能家居线下选购指南:逛浦东建材市场后总结的避坑经验

智能家居线下选购指南:逛浦东建材市场后总结的避坑经验

朋友家最近在装修,连着问了我三次同一个问题:上海买智能家居哪里好?前两次我都甩链接让他去网上看评测,直到他自己跑了一趟浦东的建材市场,回来一脸认真地跟我说,你天天研究这些,估计都没认真逛…

2026/9/24 18:31:16 阅读更多 →
高德JSAPI叠加GeoServer WMS:从白屏到坐标系对齐的实战指南

高德JSAPI叠加GeoServer WMS:从白屏到坐标系对齐的实战指南

最近在做一个内部的GIS数据可视化项目,要在高德JSAPI 2.0的地图上叠加GeoServer发布的WMS图层,第一反应是直接用现成的AMap.TileLayer.WMS,谁想到一个看起来不复杂的功能,硬是折腾了两天。图层白屏、跨域报错、坐标系偏移&#xf…

2026/9/24 18:31:16 阅读更多 →
OpenClaw搭建实战:WSL2环境、千问接入与飞书Channel排坑

OpenClaw搭建实战:WSL2环境、千问接入与飞书Channel排坑

OpenClaw 最近的热度确实离谱,群里天天有人问怎么装、怎么配、为什么跑不起来。我前前后后帮朋友远程排查过好几轮,从 Windows 到 Linux 到 WSL2 都踩过一遍,踩坑记录都快攒成一本小册子了。这篇我就把整套搭建流程拆开揉碎,从环境…

2026/9/24 18:31:15 阅读更多 →
Flutter for OpenHarmony单元测试:用mocktail实现无代码生成的Mock方案

Flutter for OpenHarmony单元测试:用mocktail实现无代码生成的Mock方案

在 Flutter for OpenHarmony 这类适配型工程里做单元测试,最让人头疼的往往不是业务逻辑本身,而是环境依赖。我最早在一个鸿蒙设备的 Flutter 项目里跑flutter test,第一轮测试就全被MissingPluginException淹没——原因很简单:测…

2026/9/24 18:30:15 阅读更多 →

日新闻

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为…

2026/9/24 0:00:19 阅读更多 →
单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

简介:一份基于单细胞RNA测序数据的细胞类型注释算法研究Python毕业设计源码,针对计算机相关专业正在做毕设或需要项目实战的学习者,可用于课程设计与期末大作业。项目代码完整、经导师指导评审通过,可直接运行,覆盖数据…

2026/9/24 0:00:19 阅读更多 →
C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

第一次在项目里被反射卡住,是在一个老旧的WinForms模块里:几十个类依赖PropertyChanged通知,运行时反射读属性、发通知,每次启动慢半拍不说,一上.NET Native/AOT裁剪模式几乎全面崩盘。后来我把这段逻辑全部改成C#源生…

2026/9/24 0:00:19 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/24 9:10:42 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →