GraphQL 中的订阅和实时更新

GraphQL 是一种用于API的查询语言,它由Facebook开发并于2015年发布。与REST API不同,GraphQL并不遵循固定的URL结构或HTTP方法。它允许您精确地指定需要提取的数据,并且减少了不必要的资源获取。此外,GraphQL还具有一项出众功能,即订阅和实时更新。

什么是订阅和实时更新

订阅是一种类似于长轮询的技术,它允许客户端与服务器之间建立一个持久的连接并保持打开状态,从而可以及时获取与查询相关的任何事件更新。订阅的实现方式是WebSocket协议,这是一种基于TCP协议的传输层协议,可以提供实时和双向的数据传输。

实时更新是指当后端数据发生更改时,前端自动及时更新的过程。这种实时更新的实现方式常常使用WebSocket进行实现,以实现真正的实时更新,而不只是在用户请求时及时返回数据。鉴于其高效和便利性,订阅和实时更新正在快速走向前端开发的主流趋势。

如何在GraphQL中实现订阅和实时更新

首先,需要在后台服务器上使用GraphQL Subscriptions来启用该功能。GraphQL Subscriptions是GraphQL规范的补充,是一种Server-to-Client模式的实现方式。此外,还需要使用Apollo Client、GraphQL Yoga等前端库,以便能够在前端应用程序中进行订阅和实时更新。

下面我们使用GraphQL Subscriptions和Apollo Client来实现一个简单的聊天程序的订阅和实时更新功能:

1. 准备工作

首先,我们需要在后端服务器上使用GraphQL Subscriptions来启用该功能。

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

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

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

在上面的代码中,我们使用subscriptions-transport-ws库来启动服务器使用WebSocket协议。接着,我们创建了一个HTTP服务器,并将其与我们的WebSocket服务器进行了连接。我们还将subscriptions-transport-ws库提供的createSubscription函数公开在服务路线上。

2. 创建数据库

在这个例子中,可以用以下方法来创建一个内存数据库来存储聊天室历史记录和正在进行的会话:

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

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

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

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

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

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

在上面的代码中,我们定义了一个空“消息”数组,一个空的“会话”对象,以及一些操作这些对象的函数。

3. 定义 GraphQL schema

我们使用GraphQL schema来描述数据模型以及客户端如何请求它。下面是我们用来查询当前消息记录和创建新消息的查询和突变。

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

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

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

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

我们定义了一个messages字段来查询当前“消息”记录。我们还定义了一个sendMessage突变,用于向聊天室发送新消息。

4. 编写subscription

现在,我们可以通过GraphQL Subscriptions定义订阅。这将使用WebSocket来建立与客户端的长期连接,并在后端数据发生更改时通知它们。以下是用于订阅新消息的定义。

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

我们定义了一个messageSent订阅,用于订阅发生在给定“ sessionId”的新消息。

5. 在前端应用程序中编写客户端代码

对于前端应用程序,我们将使用Apollo Client和subscriptions-transport-ws库来建立与后端服务器的WebSocket连接,并从“ messageSent”订阅接收消息。

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

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

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

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

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

上面的代码创建了Apollo Client,并使其可以与我们的WebSocket服务器建立连接。我们确保我们和HTTP服务器也建立了连接。我们使用split()函数来组合这两个链接。

现在,我们可以使用我们编写的订阅消息的代码来从后端服务器接收聊天消息。以下是完整的代码:

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

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

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

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

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

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

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

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

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

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

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

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

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

当我们运行代码时,在前端应用程序中,我们可以看到自动实时更新聊天框中的消息,从而实现了订阅和实时更新的功能。

结论

GraphQL的订阅和实时更新机制使得开发实时应用变得更加便捷和高效,能够大幅缩短数据更新的延迟时间,更好地实现数据的实时传输,同时也能够更好地保证数据安全。在实际开发项目中,考虑实时应用或者及时更新的需求,GraphQL的订阅和实时更新机制尤其值得注意。这里我们提供了一个简单的聊天程序的例子,讲述了如何使用Apollo Client、GraphQL Subscriptions来实现基于WebSocket的订阅和实时更新机制。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/670f21aa5f55128102630719