GraphQL中的subscription使用方法

阅读时长 11 分钟读完

GraphQL是一种查询语言,它可以帮助开发者更好的管理应用程序的数据。GraphQL中的subscription是一种实时的数据获取方式,它能够使客户端实时收到服务端的数据更新通知。本文将介绍GraphQL中的subscription使用方法,并提供一些示例代码。

Subscription是什么?

Subscription是GraphQL中一种实时的数据获取方式。相比查询和变更,Subscription使得客户端可以实时地获得服务端可能的数据改变。

Subscription 的用法类似于GraphQL中的查询语句,不同之处在于订阅会创建一个 WebSocket 连接,并监听它们之间的数据传输。当服务端相应的数据发生变化时,它会通过WebSocket连接将数据实时推送给客户端。

Subscription的使用

使用Subscription需要以下步骤:

1. 在服务端的GraphQL Schema中定义Subscription类型

在服务端定义Subscription类型,Subscription类型应该包含客户端所需要监听数据的字段。比如,客户端需要监听用户行为,那么我们需要在服务端的GraphQL Schema中定义一个subscription类型:

其中,userActivity是我们所定义的字段名,它接收一个参数userId,类型为ID,返回值为UserActivity类型。这个Subscription类型代表着客户端可以在服务端请求userActivity数据,并且服务端可能会实时地发送更新给客户端。

2. 编写subscription的解析器

在服务端,我们需要编写一个处理userActivity字段的解析器。这个解析器将接收从客户端发送过来的subscription请求,并处理给定的参数,使用某些方法来获取新的userActivity数据。最后,使用函数pubsub.publish,将新数据推送给绑定的客户端。

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

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

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

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

这个解析器函数首先创建PubSub实例,当有连接的客户端发来请求时,解析器发现此连接还没有订阅该频道,所以只需创建一个订阅传输通道并返回即可,GraphQL-JS库内部的pubsub.asyncIterator(channel)函数可以实现这个功能。

如果有来自Mutation的用户活动更新,解析器将使用getUserActivity()函数获取新的userActivity数据。最后,使用函数pubsub.publish将新数据推送给订阅过该频道的客户端。

3. 在客户端使用GraphQL客户端库

在客户端,我们需要使用GraphQL客户端库进行请求subscription。如果您使用的是Relay Modern或Apollo Client,这已经得到了良好的支持。

但如果您需要实现自定义的GraphQL客户端,可以使用Subscription.js这个库,在客户端使用它来执行Subscription查询和建立WebSocket连接。下面是一个使用原生fetch和Websockets API 的示例:

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

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

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

这段JS代码会发起一个WebSocket的连接并发送一个subscription的请求。代码中的query变量,是我们通过WebSocket发起的请求所发送的subscription的查询语句。变量vars则是用来提供给GraphQL语句的参数。

收到的WebSocket消息应该和从HTTP POST和GET请求得到的一样。其返回数据被当做WebSocket消息的“data”属性传递。最后收到的WebSocket消息将在控制台中显示。

订阅 示例

现在,我们以一个简单的实例来演示Subscription由于配有WebSocket实时收到数据的过程。我们使用Apollo Server、React和Subscription.js完成本示例.

服务器端实现

首先我们创建一个GraphQL的服务。下面是一个使用了Express框架和Apollo Server的例子。

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

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

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

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

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

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

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

这里的resolvers中,Mutation.updateUserActivity函数用来更新用户活动,使用pubsub.publish(USER_ACTIVITY_CHANGED, { userActivity: usersActivity[id] });函数将更新的数据推送给所有订阅了该频道的客户端。

Subscription.userActivity({ id })是客户端请求的subscription,调用pubsub.asyncIterator(USER_ACTIVITY_CHANGED)函数创建websocket描述符,返回是一个可迭代的对象。

客户端实现

在客户端,我们使用Subscription.js来从服务器端订阅数据的更新。使用react hooks(useEffect和useState)将获得websocket的请求并处理websocket消息。此外,还将使用Subscription来监听来自服务器的数据更新。

在App.js中编写以下代码:

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

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

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

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

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

总结

通过这篇文章,您可以学习到GraphQL中subscription的使用方法。这是一个非常强大的特性,可以让客户端实时地收到服务端数据的更新。Subscription与传统的Ajax轮询相比,具有更好的性能和代码可读性。当您开发一个实时的应用程序时,subscription会毫不犹豫地让您的代码更简洁和高效。

除了以上的示例,GraphQL还有很多其他的功能和应用场景。如果您现在使用的RESTful API存在一些问题,可以考虑使用GraphQL和它的subscription, 或者其他特性来实现您的应用程序。

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

纠错
反馈