GraphQL 如何处理循环引用

阅读时长 7 分钟读完

在前端开发中,GraphQL 是一种独特的 API 查询语言,它能够提供更加高效和灵活的 API 查询方式。然而,对于前端开发人员,循环引用是一个比较棘手的问题。在 GraphQL 中,处理循环引用的方法需要考虑性能和复杂度。本文将会介绍 GraphQL 处理循环引用的方法,帮助读者更好地理解 GraphQL,以及在项目中更好地使用它。

什么是循环引用

在前端开发中,循环引用是比较常见的一种问题。循环引用指的是对象之间相互引用的情况。比如说,一个对象中的属性引用了另一个对象,而那个对象又引用回来了此对象。而这种引用的情况在 GraphQL 中特别容易发生。比如说,我们有了两个类型 UserPostUser 中含有用户的所有帖子列表,而Post又含有这个帖子所属的用户。这时候我们就需要使用 GraphQL 提供的防止循环引用的方法,否则将导致性能上的问题。

解决方法

1. 使用 Resolve 函数的第二个参数

使用 Resolve 函数的第二个参数是常见的方法。在使用 GraphQL 查询时,我们可以使用解析器函数进行解析。在解析器函数中,我们可以访问查询中的所有字段和他们的值。当我们在一个类型中含有另一个类型的引用时,我们需要调用一个第二个参数。这个参数是一个标识,用来避免无限递归。下面是一个示例代码:

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

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

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

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

----- ------ - --- --------------
    ---------
    ----------
    -------- - ----- --
---
展开代码

上述代码中,我们使用了一个第三个参数 context,传入了我们的 users 数据。在 Post 类型的解析器函数中,我们可以直接去访问 users 数据,再去过滤符合条件的数据即可。这里我们使用了使用了一个默认的限制级别,防止无限递归。这个限制级别指定了一个最大的递归深度,保障程序的性能。

2. 使用 DataLoader

DataLoader 是一个第三方库,能够减少 GraphQL 查询时的重复查询。这个库将会缓存查询过的数据,再次使用相同查询能从内存中获取,不必再次进行查询操作。但是在循环查询之间,它需要使用一个垫片,来防止循环查询导致死循环。下面是用 DataLoader 库来解决循环引用的示例代码:

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

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

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

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

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

----- ------ - --- --------------
    ---------
    ----------
    -------- - ---------- --
---
展开代码

在上述代码中,我们通常会得到循环引用的 UserPost 对象。对于 User 类型解析器函数查询对象时,将会得到该用户用户的所有帖子。 Post 类型解析器函数查询用户时,将会得到该帖子所属的用户。这种情况下,我们可以使用 DataLoader 支持的批处理查询功能,防止这些查询的重复执行。

注意事项

1. 数据必须缓存

使用前述两种方法的其中一种,缓存查询过的数据是必要的。因为之前的查询中的查询结果只有在第二次查询的时候才会使用,要不就是完全不用。因此我们需要缓存之前的查询结果,以便在下次查询时使用。GraphQL 自己是没办法缓存查询结果的,因此在处理循环引用时,我们需要注意数据的缓存。

2. 对于较大的数据,使用数据库

对于大型数据,并不适合存储在内存中。在这种情况下,我们可以使用数据库来解决这个问题。 GraphQL 处理数据库和其他数据源的方法是相似的。应当将查询数据库的部分处理到解析器函数的子函数内,在查询的过程中使用 async-await 异步函数解决查询的问题。

结束语

文章简要介绍了 GraphQL 处理循环引用的方法,帮助读者更加深入了解 GraphQL,并在项目中更好地使用它。GraphQL 是一个非常优秀的 API 查询语言,它能够容易的对数据进行查询和修改。防止循环引用是 GraphQL 中需要注意的问题之一,希望上述方法能够有所帮助。

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

纠错
反馈

纠错反馈