Apollo Server/Client 的 GraphQL 实现与 bug 总结

GraphQL 是一种用于 API 的查询语言,它使得客户端可以精确地请求需要的数据,避免了传统 RESTful API 中的 over-fetching 和 under-fetching 的问题。而 Apollo Server/Client 是一套基于 GraphQL 的全栈解决方案,它包含了一个高性能的 GraphQL 服务器和一个用于构建客户端的 GraphQL 客户端库。本文将会介绍 Apollo Server/Client 的 GraphQL 实现以及在使用过程中可能遇到的 bug,以及如何解决这些 bug。

Apollo Server

GraphQL Schema

GraphQL Schema 定义了一个 GraphQL API 的类型、字段、查询、变量等信息。在 Apollo Server 中,我们可以使用 GraphQL schema language 或者 JavaScript 来定义 GraphQL schema。下面是一个使用 GraphQL schema language 定义的简单的 schema:

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

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

这个 schema 定义了一个 Query 类型,它有一个名为 hello 的字段,类型为 String。同时,这个 schema 定义了一个名为 query 的 schema。

Resolvers

GraphQL Resolver 是一个函数,它负责处理一个 GraphQL 查询,并返回一个结果。在 Apollo Server 中,我们可以使用 JavaScript 编写 Resolver。下面是一个简单的 Resolver:

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

这个 Resolver 处理了一个名为 hello 的查询,并返回一个字符串 "Hello World!"。

数据源

在实际的应用中,数据通常来自于数据库、第三方 API 或者其他的数据源。在 Apollo Server 中,我们可以使用 data source 来管理这些数据源。下面是一个使用 data source 的例子:

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

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

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

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

这个例子中,我们创建了一个 UserAPI 的 data source,它包含了一个 users 数组,每个元素都有一个 id 和一个 name。getUserById 方法可以根据 id 查找对应的用户。

Bug 总结

1. 数据库查询出错

在使用 data source 的过程中,如果我们使用了数据库作为数据源,有时候会遇到查询出错的问题。这个问题通常是因为数据库连接池中的连接没有正确释放导致的。解决这个问题的方法是在每次查询完成后手动释放连接。

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

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

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

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

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

2. 数据源缓存不更新

在使用 data source 的过程中,如果我们使用了缓存,有时候会遇到缓存不更新的问题。这个问题通常是因为缓存没有正确的更新导致的。解决这个问题的方法是在每次更新数据源后手动更新缓存。

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

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

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

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

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

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

这个例子中,我们在 addUser 方法中手动触发了一个 userAdded 事件,在 subscriptions 中监听这个事件,并手动发送一个 USER_ADDED 消息。

Apollo Client

GraphQL Query

在 Apollo Client 中,我们可以使用 GraphQL Query 来查询数据。下面是一个简单的 Query:

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

这个 Query 查询了一个名为 users 的字段,它包含了两个字段,id 和 name。

React Hooks

在 React 中,我们可以使用 Apollo Client 提供的 React Hooks 来查询数据。下面是一个使用 useQuery Hooks 的例子:

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

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

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

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

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

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

这个例子中,我们使用了 useQuery Hooks 来查询数据,并在组件中渲染了查询结果。

Mutation

在 Apollo Client 中,我们可以使用 Mutation 来修改数据。下面是一个简单的 Mutation:

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

这个 Mutation 接受一个名为 input 的变量,并返回一个包含 id 和 name 的对象。

React Hooks

在 React 中,我们可以使用 Apollo Client 提供的 React Hooks 来执行 Mutation。下面是一个使用 useMutation Hooks 的例子:

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

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

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

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

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

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

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

这个例子中,我们使用了 useMutation Hooks 来执行 Mutation,并在组件中渲染了 Mutation 的结果。

Bug 总结

1. 缓存不清理

在使用 Apollo Client 的过程中,如果我们使用了缓存,有时候会遇到缓存不清理的问题。这个问题通常是因为缓存没有正确的清理导致的。解决这个问题的方法是手动清理缓存。

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

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

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

这个例子中,我们手动修改了缓存中的数据,并手动清理了缓存中的数据。

2. 多个请求并发

在使用 Apollo Client 的过程中,如果我们同时发起多个请求,有时候会遇到多个请求并发的问题。这个问题通常是因为多个请求共享同一个缓存导致的。解决这个问题的方法是为每个请求创建一个独立的缓存。

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

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

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

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

这个例子中,我们为每个请求创建一个独立的缓存,并使用这个缓存来查询数据。

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