GraphQL 中的订阅(Subscription)实例教程

阅读时长 8 分钟读完

GraphQL 是新一代 API 技术,它能提高前端和后端之间的数据交互效率,让 Web 服务开发变得更加容易和快速。其中,GraphQL 的 Subscription 特性是一项重要的功能,它允许前端实时订阅后端数据的变化,重新定义了数据交互的方式。本文将为大家讲解 GraphQL 中的订阅(Subscription)实例教程,通过详细的案例,帮助大家深入学习和掌握该功能的使用方法。

什么是 GraphQL Subscription?

GraphQL Subscription 是 GraphQL 的一项实时数据查询功能,通过 Subscription,前端可以实时订阅后端的数据变化,当后端数据发生变化时,前端能立即收到推送消息。这与传统的轮询方式相比,可以提高数据交互效率,减少无效请求,使 Web 应用更加流畅和响应式。

要使用 GraphQL Subscription,需要实现一个 Subscription Type,该类型包含一个订阅器(resolver function),在服务器端将新的数据推送给客户端。同时,前端也需要定义一个 Subscription Query,通过这个 Subscription Query 可以实时订阅后端数据的变化。

GraphQL Subscription 的使用示例

接下来,我们将通过一个具有实际意义的示例,讲解 GraphQL Subscription 的使用方法。

在本示例中,我们将使用一个具有实时性需求的聊天室,用户可以在该聊天室发送消息,同时能实时接收到其他用户发送的消息。以下是该示例实现的步骤:

1. 定义 GraphQL Schema

首先,我们需要定义 GraphQL Schema,用于描述我们要实现的数据模型和订阅功能。在该示例中,我们需要定义两个类型:Message 和 Subscription,其中 Message 类型用于描述聊天室中的消息,Subscription 类型用于实现消息推送功能。以下是该 Schema 的实现代码:

-- -------------------- ---- -------
---- ------- -
  --- ---
  -------- -------
  ----- -------
-

---- ------------ -
  ----------- --------
-

---- ----- -
  --------- -----------
-

以上代码实现了 Message、Subscription、Query 三种类型,其中:

  • Message 类型定义了消息的 id、content 和 user;
  • Subscription 类型定义了名为 newMessage 的订阅器,该订阅器用于在有新消息时,通过指定的 resolver function,将新消息推送给客户端;
  • Query 类型定义了名为 messages 的查询,该查询返回所有之前发送的消息。

以上代码示例中,在 Subscription 类型中定义了一个叫做 newMessage 的订阅器,在客户端订阅该订阅器时,服务端将在有新消息时通过订阅器返回该消息的详细信息。

2. 实现 Resolver Function

接下来,我们需要实现 Resolver Function,用于处理客户端的查询和订阅请求,我们需要实现如下四种 Resolver Function:

  • Query resolver:用于处理客户端的普通查询请求;
  • Subscription resolver:用于在有新消息时,将消息详细信息推送给客户端;
  • Mutation resolver:用于处理客户端的修改请求,例如发送新的消息;
  • Resolver for Message type:用于定义 Message 类型的数据获取方式。

在本示例中,我们需要实现两个 Resolver Function:

-- -------------------- ---- -------
----- --------- - -
  ------ -
    --------- -- -- --------
  --
  ------------- -
    ----------- -
      ---------- -- -- ---------------------------------------
    -
  -
-

以上代码中,我们定义了两个 Resolver Function,分别用于 Query 和 Subscription 类型:

  • Query 类型的 Resolver 函数 messages,将返回所有消息;
  • Subscription 类型的 Resolver 函数 newMessage,用于处理订阅请求,将返回在 NEW_MESSAGE_TOPIC 上注册的 resolver function。

3. 集成 pubsub

对于 Subscription resolver,我们需要使用 pubsub 来实现订阅功能,该功能需要与底层的 pubsub 库进行集成,以便可以在后端推送新的消息。

在本示例中,我们将使用 Node.js 的 Redis 库提供的 pubsub 库,实现订阅功能。以下是集成 pubsub 的代码实现:

-- -------------------- ---- -------
-- -- ----- -
----- ----- - -------------------

-- ---- ------- --
----- ------ - --- --------

-- ---- ----- --
----- ----------------- - -------------

-- - -------- -------- ------
----- -------- ------------------- - -------- ---- -- - ------ -- -
  ----- ------- - - --- --------------- - -- -------- ---- --
  -----------------------
  ----- --------------------------------- - ----------- ------- ---
  ------ --------
-

-- -- -------- --- ------
----- -------- - ----
  ---- -------- -
    -------------------- -------- ----- --------- --------
  -
--

-- -- -------- --------
----- --------- - -
  --------- -
    -----------
  -
--

以上代码实现了以下功能:

  • 通过 Redis 提供的 pubsub 库创建 pubsub 实例;
  • 定义订阅 Topic 名称 NEW_MESSAGE_TOPIC;
  • 在 Mutation resolver 中通过 pubsub 实例,将新消息发布到 NEW_MESSAGE_TOPIC 上;
  • 在 Mutation resolver 中定义 mutation 函数 sendMessage 用于发布新的消息。

4. 客户端订阅实例

最后,我们需要实现客户端的订阅功能,以便通过 Subscription 获取到服务端推送的消息。以下是客户端订阅的实现代码:

-- -------------------- ---- -------
----- ------------------------ - ----
  ------------ -
    ---------- -
      --
      ----
      -------
    -
  -
--

-------- ---------- -
  ----- ---------- ------------ - -------------
  ----- ------------- - -----------------------------------
  ----- - ----- ---------- - - ----------------
    ------------------------
  --

  ------------ -- -
    ------------------------- ------------------------
  -- --------------

  ----- ---------------- - ----- ------- -- -
    -----------------------
    ----- -------------
      ---------- -
        -------- --------
        ----- --------
      -
    ---
  --

  -- ------ ------- ----- ----- ----- ----
-

以上示例代码实现了如下功能:

  • 定义名为 NEW_MESSAGE_SUBSCRIPTION 的 GraphQL Subscription Query;
  • 使用 useSubscription Hook 订阅 NEW_MESSAGE_SUBSCRIPTION;
  • 定义 handleNewMessage 函数用于发送消息;
  • render 消息列表和发送消息的表单。

在客户端订阅 NEW_MESSAGE_SUBSCRIPTION Topic 后,当服务端有新消息时,客户端会立即收到推送消息,从而更新聊天记录。

结论

通过以上示例,我们可以看到 GraphQL Subscription 能够实现前端对后端数据的实时订阅,实现了推送式的数据更新,带来了更流畅、更实时的 Web 体验,同时也能减少无效数据交互和浪费的资源。以上示例也提供了一个实际项目的应用,对于进一步学习 GraphQL 技术和实现实时 Web 应用具有指导意义。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67136ef8ad1e889fe20cdf8b

纠错
反馈