1. 前言
现今的 web 应用场景越来越复杂,需要应对的数据也变得越来越多。传统的 RESTful API 往往会面临一些挑战,例如数据量变得越来越大,渲染速度变得越来越慢等。GraphQL 就成了一个解决这些问题的好方案。
Relay 是 Facebook 内部最早开发的针对 React 的 GraphQL 客户端。Relay 与 GraphQL 相辅相成,能够帮助开发者更轻松地发起请求并处理返回的数据。
本文将针对 Relay 中的 Subscription,介绍如何通过使用 npm 包 relay-classic-subscriptions 来实现。
2. 什么是 Subscription
在 GraphQL 中,Subscription 用于订阅一些与后端相关的事件,例如新建用户数据、上传图片、更新等等。与 Query 和 Mutation 不同,Subscription 返回的不是一次性的结果数据,而是随着事件不断发生的新数据。
3. 为何使用 relay-classic-subscriptions
Relay 本身并不提供 Subscription 的实现方式,因此我们需要借助一些第三方开源工具库。其中 relay-classic-subscriptions 是一个相对比较稳定的工具库,适用于 Relay Classic 的版本。
其主要功能是:通过与 graphql-subscriptions 结合使用,实现 Subscription 的动态响应。
4. 使用教程
这里我们将针对一个简单的例子来演示如何使用 relay-classic-subscriptions 来实现实时的服务器端推送消息至前端。
4.1 使用 graphql-subscriptions
首先,我们需要在后台服务中引入 graphql-subscriptions 包。该包提供了与 graphql-tools 所提供的订阅解析器一样的 API。
const { SubscriptionManager } = require("graphql-subscriptions");
接着,我们需要创建 SubscriptionManager 对象,用于处理 Subscription 请求。
const subscriptionManager = new SubscriptionManager({ schema, setupFunctions, });
其中,我们需要将 GraphQL 的 schema 以及一个 setupFunctions 集合传递给 SubscriptionManager 对象。setupFunctions 具体说明下面会介绍。
4.2 安装 relay-classic-subscriptions
接着,我们需要将 relay-classic-subscriptions 包安装至前端项目中。
yarn add relay-classic-subscriptions
4.3 前端代码
在前端代码中使用 relay-classic-subscriptions,需要以下两个步骤:
- 创建一个 SubscriptionDescriptor。
const subscriptionDescriptor = { subscription: /* GraphQL subscription document */, variables: /* GraphQL subscription variables */, onError: (error) => console.error(`Error: ${error.stack}`), onNext: (payload) => { console.log(`Received data: ${JSON.stringify(payload)}`); }, };
以上代码中,subscription 和 variables 分别对应我们要监听的事件和提供代码所需要的参数。
onError 和 onNext 回调函数在监听到事件时会被调用。其中,onNext 负责处理接收到的数据。
- 启动 Subscription
const { requestSubscription } = require("relay-runtime"); const subscription = requestSubscription( environment, subscriptionDescriptor );
以上代码中,我们使用 requestSubscription 来启动 Subscription。其中,environment 对应一个运行中的 Relay 环境,subscriptionDescriptor 则是 SubscriptionDescriptor 对象。
4.4 后端代码
回头看第 4.1 节中的 setupFunctions,它包含一个数组,每一项都是一个函数。这些函数用于处理 Subscription 的数据查询。
const setupFunctions = { mySubscription: (_, { appId }) => ({ myIterator: mySubscriptionIterator(appId), }), };
在 setupFunctions 中,我们通过获取 appId 参数创建了一个 SubscriptionIterator。mySubscriptionIterator 负责监听服务端推送的数据事件,并反馈给 SubscriptionManager。
-- -------------------- ---- ------- ----- ---------------------- - ------- -- - ------ - ----- ------------------------- - ----- ------------ - --------------------------------------------- ----- ------ - ----- ------- - ----- --------------------------------- -- -------------- ----- ------------- - -- -- --
5. 总结
relay-classic-subscriptions 使得实现基于 Subscription 的 Relay 程序相对简单。我们能用它来监听后台运行中的事件并实时向前端推送数据更新。通过本篇文章的学习,希望能够帮助读者更好地利用 Relay 进行开发。
6. 示例代码
前端代码:
-- -------------------- ---- ------- ----- - ------------------- - - ------------------------- ----- ---------------------- - - ------------- -------- ------------ ---------------------- ---- - --------------------- ------- - ---- - - -- ---------- - ----- -- ------- --------- -- --------------------- ------- --------- -------- ------- -- --------------------------- ------ ----------- -- ----- ------------ - -------------------------------- ------------------------
后端代码:
-- -------------------- ---- ------- ----- - ------ - - --------------------------------- ----- ------ - --- --------- ----- ---------------------- - ------- -- - ------ - ----- ------------------------- - ----- ------------ - --------------------------------------------- ----- ------ - ----- ------- - ----- --------------------------------- -- -------------- ----- ------------- - -- -- -- ----- -------------- - - --------------- --- - ----- -- -- -- ----------- ------------------------------ --- --
全代码实现可以参考:Relay Subscription Example。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/60055b0f81e8991b448d8b94