首页/新闻资讯/正文详情

Relay `requestSubscription` API 完全指南:以命令式方式建立 GraphQL 订阅

发布时间:2026/9/23 5:23:07 来源:云帆数科 栏目:资讯中心
Relay `requestSubscription` API 完全指南:以命令式方式建立 GraphQL 订阅
前端开发工具【免费下载链接】relayRelay is a JavaScript framework for building>项目地址https://gitcode.com/gh_mirrors/relay29/relay点击查看免费下载requestSubscription是 Relaypackages/react-relay提供的命令式imperative订阅 API用于在任意时机例如事件回调、服务端推送触发时建立 GraphQL Subscription并在收到服务端事件流数据后自动将其规范化并写入 Relay Store驱动依赖数据的组件实时刷新。阅读本文后你将掌握requestSubscription(environment, config)的完整签名、GraphQLSubscriptionConfig中每一个配置字段的含义与底层实现、Disposable返回值的使用方式以及如何借助updater、声明式指令declarative directives和网络层 WebSocket 配置将其落地到真实应用。本文以 version-v17.0.0 的 requestSubscription 参考文档 为主体骨架结合relay-runtime与react-relay的源码实现与单元测试展开讲解。requestSubscription是什么requestSubscription是一个命令式 API用于建立 GraphQL Subscription。它与 React Hooks 中声明式的useSubscription形成互补Hook 适合在组件挂载时自动建立订阅而requestSubscription可以在任何 JavaScript 环境中调用——包括事件处理器、定时任务、非组件模块等场景。import {graphql, requestSubscription} from react-relay; const subscription graphql subscription UserDataSubscription($input: InputData!) { # ... } ; function createSubscription(environment: IEnvironment): Disposable { return requestSubscription(environment, { subscription, variables: {input: {userId: 4}}, }); }从源码看requestSubscription.jsrequestSubscription内部的核心调用链为通过getRequest(config.subscription)解析graphql标签生成的请求描述校验operationKind必须是subscription否则直接抛错requestSubscription: Must use Subscription operation使用createOperationDescriptor(subscription, variables, cacheConfig)构造操作描述符调用environment.executeSubscription({operation, updater})获得一个RelayObservable对该 Observable.subscribe({complete, error, next})把回调映射为onCompleted/onError/onNext返回一个封装了sub.unsubscribe的Disposable。参数ArgumentsrequestSubscription接受两个参数environment一个 Relay Environment实现 RelayStoreTypes 中的 IEnvironment。通常来自useRelayEnvironment()或者应用顶层创建的RelayModernEnvironment实例。config类型为GraphQLSubscriptionConfigTSubscriptionPayload的配置对象其字段详见下文。GraphQLSubscriptionConfig配置字段详解以下字段定义源自 GraphQLSubscriptionConfig.md同时与 requestSubscription.d.ts 中的 TypeScript 类型一一对应字段类型必填说明subscriptionGraphQLTaggedNode是使用graphql模板字符串声明的订阅操作variablesVariables是传递给订阅操作的变量cacheConfigCacheConfig否缓存与传输配置见下文onCompleted() void否服务端结束订阅complete时执行的回调onError(error: Error) void否订阅出错时执行的回调onNext(payload: TSubscriptionPayload) void否收到新数据时执行的回调updaterSelectorStoreUpdater否命令式读写 Relay Store 的更新函数configsArrayDeclarativeMutationConfig否声明式变更配置与updater互斥subscription使用graphql标签声明订阅与查询query和变更mutation一样订阅也通过graphql标签声明区别在于顶层关键字是subscription。Relay 编译器会为订阅操作生成对应的类型因此GraphQLSubscriptionConfig可以携带泛型参数实现静态类型检查——这是官方推荐的最佳实践。一个订阅示例源自 graphql-subscriptions.mdxsubscription FeedbackLikeSubscription($input: FeedbackLikeSubscribeData!) { feedback_like_subscribe(data: $input) { feedback { like_count } } }feedback_like_subscribe是订阅根字段subscription root field它在后端建立事件流订阅建立后每当该事件流产生事件客户端就会收到一个形如下面的 payloadRelay 会将其规范化并合并进 Store{ feedback_like_subscribe: { feedback: { id: feedback-id, like_count: 321 } } }由于Feedback类型包含id字段Relay 编译器会自动为订阅补上id的选择收到响应后Relay 会在 Store 中按id匹配对应记录并更新字段值凡是依赖这些字段的组件都会自动重渲染。variables订阅变量与查询/片段一样订阅可以引用 GraphQL 变量variables字段用于传入这些变量的具体值。示例中{input: {userId: 4}}即传入订阅所需的输入参数。cacheConfig缓存与传输配置cacheConfig的类型为CacheConfig其可选字段定义于 CacheConfig.md字段类型说明forceboolean为true时无条件发起请求忽略任何配置的响应缓存状态pollnumber以指定毫秒间隔轮询实现实时更新该值会被传给setTimeoutliveConfigIdstring通过调用 GraphQLLiveQuery 实现实时更新表示做 live query 时网关的一种配置metadataobject用户自定义元数据transactionIdstring用户提供、用于唯一标识某次操作执行实例的值在 requestSubscription.js 中cacheConfig会被透传给createOperationDescriptor最终由environment.executeSubscription传递给网络层执行函数见 RelayModernEnvironment.js 中this.getNetwork().execute(operation.request.node.params, operation.request.variables, operation.request.cacheConfig || {}, null)。因此metadata等字段可以原样到达你的网络层 fetch/subscribe 函数用于埋点、追踪等场景——这一点也被测试用例requestSubscription() cacheConfig所验证requestSubscription-test.js。onCompleted/onError/onNext订阅生命周期回调这三个回调分别对应订阅的三个生命周期事件onNext收到订阅 payload 时执行参数是订阅响应数据在片段展开边界处停止源码中会先通过environment.lookup(selector).data从 Store 读取数据再传给回调requestSubscription.js。onError订阅出错时执行参数为错误对象。onCompleted服务端结束订阅流关闭时执行。updater命令式更新 Relay Storeupdater的类型为SelectorStoreUpdater签名是(store: RecordSourceSelectorProxy, data) void。通过它你可以命令式地直接读写 Relay Store从而对订阅 payload 的落库方式拥有完全控制权可以创建全新的记录record也可以更新或删除已有记录。完整的 Store 读写 API 可参见 store 参考文档。从源码看当configs与updater同时提供时requestSubscription会输出一条 warningrequestSubscription: Expected only one of updater and configs to be providedrequestSubscription.js即两者互斥只能二选一。configs声明式变更配置configs允许你使用DeclarativeMutationConfig以声明方式描述 Store 变更最常见的场景是把新到达的数据追加到某个 connection。源码中若提供了configs会通过RelayDeclarativeMutationConfig.convert(configs, subscription, null /* optimisticUpdater */, config.updater)将其转换为updaterrequestSubscription.js。测试用例Config: RANGE_ADDrequestSubscription-test.js演示了完整用法用RANGE_ADD配置把新评论追加到FeedbackCommentQuery_comments连接上const configs [ { type: RANGE_ADD, connectionName: comments, connectionInfo: [ { key: FeedbackCommentQuery_comments, rangeBehavior: append, }, ], parentID: feedbackId, edgeName: feedbackCommentEdge, }, ]; requestSubscription(environment, { configs, subscription: CommentCreateSubscription, variables: { input: {feedbackId, text: secondCommentBody}, }, });测试随后通过environment.mock.nextValue(CommentCreateSubscription, subscriptionPayload)模拟服务端推送并断言 Store 中的评论列表追加了新条目。返回值Return TypeDisposablerequestSubscription返回一个Disposable对象用于清理订阅。其接口定义于 Disposable.mdtype Disposable { dispose: () void, };调用dispose()即取消订阅源码中即sub.unsubscriberequestSubscription.js。典型用法是在组件卸载、路由切换或业务结束时调用避免内存泄漏与多余的网络连接。行为Behavior与底层实现细节操作类型强制校验requestSubscription只接受operationKind subscription的操作否则抛出requestSubscription: Must use Subscription operation错误requestSubscription.js。这保证了你不会误把 query 或 mutation 传给该 API。environment.executeSubscription调用链订阅的实际执行委托给 Environment 的executeSubscription方法RelayModernEnvironment.jsexecuteSubscription({operation, updater}) { return this._execute({ createSource: () this.getNetwork().execute( operation.request.node.params, operation.request.variables, operation.request.cacheConfig || {}, null, ), isClientPayload: false, operation, optimisticConfig: null, updater, }); }即通过网络层拿到一个「多值响应流」的RelayObservable随后_execute会逐条规范化响应数据并提交到发布队列publish queue最后通过 Store 通知订阅了相关数据的组件重渲染。注意executeSubscription与executeMutation不同它不携带乐观更新optimisticConfig: null也不强制force: true。onNext中的 rootID 处理一个值得注意的实现细节当响应带有extensions.__relay_subscription_root_id时requestSubscription会通过createReaderSelector用该 ID 替换operation.fragment的 dataID 后再lookuprequestSubscription.js。这样即使订阅期间数据被其他操作重写onNext也能读取到正确根节点下的最新数据。测试用例reads the data using the correct rootID in onNextrequestSubscription-test.js验证了这一点并确认onNext返回的数据会在片段展开边界处截断、updater恰好被调用一次。不会覆盖已有数据requestSubscription的更新是「增量合并」而非「整体替换」测试用例does not overwrite existing datarequestSubscription-test.js展示了订阅 payload 中只包含config字段时Store 中已存在的其它字段如 fragment 展开所需的isEnabled不会被清空多次推送会在连接中依次追加Mark与Zuck两条记录。实战把requestSubscription用在真实应用中场景一组件外建立订阅useSubscription的底层其实就是requestSubscription——useSubscription.js 在useEffect中调用requestSubscription(environment, config)并在清理函数中调用dispose。因此当你需要在组件生命周期之外例如全局事件总线、Web Worker 消息、导航守卫建立订阅时直接使用requestSubscription并妥善保管返回的Disposableconst disposable requestSubscription(environment, { subscription, variables: {input}, }); // 不再需要订阅时 disposable.dispose();场景二用片段展开驱动组件刷新与其在订阅中手动挑选字段更推荐直接展开组件对应的片段例如subscription FeedbackLikeSubscription($input: FeedbackLikeSubscribeData!) { feedback_like_subscribe(data: $input) { feedback { ...FeedbackDisplay_feedback ...FeedbackDetail_feedback } } }这样每当事件流产生事件FeedbackDisplay与FeedbackDetail组件所依赖的数据都会被一并更新且相比手动重查数据单次往返即可取回全部所需字段。场景三声明式指令与deleteRecord声明式变更指令declarative mutation directives在订阅中同样生效例如删除记录subscription DeletePostSubscription($input: DeletePostSubscribeData!) { delete_post_subscribe(data: $input) { deleted_post { id deleteRecord } } }场景四配置网络层以支持订阅订阅通常通过 WebSocket 传输需要为Network.create提供第二个参数subscribe函数详见 graphql-subscriptions.mdx 的网络层配置。以graphql-ws为例import {Network, Observable} from relay-runtime; import {createClient} from graphql-ws; const wsClient createClient({url: ws://localhost:3000}); const subscribe (operation, variables) { return Observable.create((sink) { return wsClient.subscribe( { operationName: operation.name, query: operation.text, variables, }, sink, ); }); }; const network Network.create(fetchQuery, subscribe);注意事项与最佳实践updater与configs不可同时提供否则会触发 warning且configs优先被转换。务必保存并调用返回的Disposable在不需要订阅时调用dispose()防止连接泄漏。onNext的 payload 会在片段展开边界处截断若需要访问片段内部数据请通过updater读写 Store。传入 Hook 的配置对象需要记忆化useMemo否则每次渲染都会重建订阅——这一点对基于requestSubscription的封装同样适用。订阅事件流与所选字段无必然关联事件流是任意的服务端推送的 payload 与客户端选择的字段之间不存在「值一定变化」的保证Relay 只负责把收到的数据规范化并合并进 Store。延伸阅读GraphQL 订阅使用指南useSubscription/requestSubscription的完整实战讲解useSubscription 源码Hook 对requestSubscription的封装requestSubscription 源码本文引用的核心实现requestSubscription 测试覆盖RANGE_ADD、cacheConfig、updater、rootID 等行为的单元测试TypeScript 类型声明GraphQLSubscriptionConfig的精确类型store 参考文档updater中可用的 Store 读写 APIupdating-data 系列指南关于 Store 更新方式的更多说明赞分享前端开发工具【免费下载链接】relayRelay is a JavaScript framework for building>项目地址https://gitcode.com/gh_mirrors/relay29/relay点击查看免费下载相关推荐Relay requestSubscription API 深度指南以命令式方式建立 GraphQL 订阅Relay requestSubscription API 深度指南以命令式方式建立 GraphQL 订阅 requestSubscription 是 Rel前端开发工具Relay requestSubscription 命令式 GraphQL 订阅 API 完全指南Relay requestSubscription 命令式 GraphQL 订阅 API 完全指南 导读 requestSubscription 是 Relay前端开发工具Relay 18 requestSubscription 完全指南命令式建立 GraphQL 订阅的 API 详解Relay 18 requestSubscription 完全指南命令式建立 GraphQL 订阅的 API 详解 导读 requestSubscriptio前端开发工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

Skill Seekers 实战指南:将文档网站、GitHub 仓库与 PDF 一键转化为 AI Skills
Skill Seekers 实战指南:将文档网站、GitHub 仓库与 PDF 一键转化为 AI Skills

人工智能AI 应用AI 技能RAGMCP 服务网页爬虫 【免费下载链接】Skill_Seekers Convert documentation websites, GitHub repositories, and PDFs into Claude AI skills with automatic conflict detection 项目地址: https://gitcode.com/gh_mirrors/sk/Skill_Seeke… · 2026/9/23 5:23:01

日差检定测试仪原理与应用全解析
日差检定测试仪原理与应用全解析

1. 日差检定测试仪的核心功能解析日差检定测试仪是钟表维修和制造行业中的专业设备,主要用于测量机械钟表或石英钟表的走时精度。所谓"日差"(Daily Rate),指的是钟表在24小时内的走时误差值,通常以秒/天为单… · 2026/9/23 5:23:01

Ceph RBD 工作负载回放工具 rbd-replay 完全指南:从轨迹采集到多客户端压测实战
Ceph RBD 工作负载回放工具 rbd-replay 完全指南:从轨迹采集到多客户端压测实战

Ceph RBD 工作负载回放工具 rbd-replay 完全指南:从轨迹采集到多客户端压测实战 【免费下载链接】ceph Ceph is a distributed object, block, and file storage platform 项目地址: https://gitcode.com/gh_mirrors/ce/ceph rbd-replay 是 Ceph 提供的分布… · 2026/9/23 5:23:01

Marp Fitting Header 指南:用 `<!-- fit -->` 注释制作自动缩放的单行标题
Marp Fitting Header 指南:用 `<!-- fit -->` 注释制作自动缩放的单行标题

前端文档 【免费下载链接】marp The entrance repository of Markdown presentation ecosystem 项目地址&#xff1a; https://gitcode.com/gh_mirrors/mar/marp 点击查看 免费下载 <!-- fit --> 是 Marp 中一个专门用于标题的 HTML 注释标记&#xff1a;只要把它放进任… · 2026/9/23 6:03:44

Johnny-Five 实战:在 Intel Edison 上驱动 Grove Q Touch 电容触摸传感器(Keypad QTOUCH)
Johnny-Five 实战:在 Intel Edison 上驱动 Grove Q Touch 电容触摸传感器(Keypad QTOUCH)

IoT机器人嵌入式 【免费下载链接】johnny-five JavaScript Robotics and IoT programming framework, developed at Bocoup. 项目地址&#xff1a; https://gitcode.com/gh_mirrors/jo/johnny-five 点击查看 免费下载 本文围绕 Johnny-Five 官方示例 docs/grove-q-touch.md 展… · 2026/9/23 6:03:44

H5应用上架iOS全流程实战指南
H5应用上架iOS全流程实战指南

1. H5项目上架iOS的核心挑战与解决方案作为一名经历过数十次H5应用上架iOS的老手&#xff0c;我深知这个过程中的痛点。很多团队在开发H5页面时游刃有余&#xff0c;但一到上架环节就手足无措。本质上&#xff0c;这是因为iOS生态有一套严格的规范体系&#xff0c;而H5作为Web技… · 2026/9/23 6:03:44

91苹果助手避坑指南:3个实战项目解决代码跑不通难题
91苹果助手避坑指南:3个实战项目解决代码跑不通难题

91苹果助手避坑指南:3个实战项目解决代码跑不通难题 刚把GitHub上扒来的91苹果助手相关代码复制进本地,结果一运行直接报错?别慌,这种“复制即崩”的坑,我踩了不下五十次。在水利信息化和前端开发的交叉领域,很多从业者容易忽略环境依赖和配… · 2026/9/23 6:03:25

工业手持终端的硬核落地:芯片、OS与硬件协同设计
工业手持终端的硬核落地:芯片、OS与硬件协同设计

1. 这不是又一款“概念机”&#xff1a;工业手持终端落地背后的三重硬门槛深开鸿联合鼎泰富推出搭载紫光展锐P7885芯片的开源鸿蒙工业手持终端——这句话在行业资讯里刷屏时&#xff0c;我正蹲在东莞一家电子厂的产线旁&#xff0c;手里捏着一台刚下线的样机。它表面看只是一台… · 2026/9/23 6:03:25

结构钢管源码拆解:3步搞定避坑指南
结构钢管源码拆解:3步搞定避坑指南

结构钢管源码拆解:3步搞定避坑指南 官方文档太长抓不住重点?别慌。很多转岗到后端或中间件开发的兄弟,一看到复杂的工业级代码就头大。今天咱们不聊虚的,直接拿【结构钢管】这个在金融、政务系统中常见的电子证照与身份核验组件开刀。我整理了一份实战避… · 2026/9/23 6:03:25

3招搞定手机怎么下载微信面试难题实战项目解析
3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧
Win7无线热点配置工具源码解析:解决API失效的3个实战技巧

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧 Win7无线热点配置工具在Win10/11上跑不动?不是你的问题,是版本升级后 API 全变了。很多老项目里的 netsh wlan… · 2026/9/23 0:00:36

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码