进阶 GraphQL:使用 Schema Directive 进行更细粒度的控制

阅读时长 6 分钟读完

GraphQL 是一种用于构建 API 的查询语言,其具有强大的类型系统和灵活的查询语法。通过使用 GraphQL,我们可以轻松地定义和查询数据模型,而不必担心与后端 API 的交互细节。

然而,在实际开发中,我们可能需要更细粒度的控制来保证 API 的安全性和可维护性。这时候,Schema Directive 就成为了一个非常有用的工具。

Schema Directive 概述

Schema Directive 是 GraphQL 中的一种元数据,它可以用来在 Schema 中为字段或类型添加额外的元数据。在使用 Schema Directive 时,我们可以通过自定义指令来实现对查询、变量、字段等细粒度的控制。

Schema Directive 的定义方式如下:

其中,directiveName 是指令名称,argumentName 是指令参数名称,ArgumentType 是参数类型,EXECUTABLE_LOCATION 是指令可以应用的位置。

常见的 EXECUTABLE_LOCATION 包括:

  • QUERY:在查询上应用指令
  • MUTATION:在变更上应用指令
  • FIELD:在字段上应用指令
  • FRAGMENT_DEFINITION:在片段定义上应用指令
  • FRAGMENT_SPREAD:在片段引用上应用指令
  • INLINE_FRAGMENT:在内联片段上应用指令

Schema Directive 示例

下面,我们通过一个简单的示例来了解如何使用 Schema Directive。

假设我们有一个 User 类型,其中包含 name 和 email 两个字段。我们希望在查询 User 类型时,只有经过身份验证的用户才能查看 email 字段。

首先,我们需要定义一个指令 @auth,用于验证用户身份:

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

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

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

在上述代码中,我们定义了一个 @auth 指令,它可以在 FIELD_DEFINITION 上应用。指令接受一个名为 requires 的参数,其默认值为 USERUser 类型中的 email 字段上使用了 @auth(requires: USER),表示只有 USER 角色的用户才能查看该字段。

下面,我们需要在解析器中实现 @auth 指令的逻辑。这里我们使用了 graphql-tools 库来实现自定义指令的解析器:

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

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

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

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

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

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

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

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

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

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

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

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

在上述代码中,我们定义了一个 AuthDirective 类,并通过 visitFieldDefinition 方法实现了 @auth 指令的逻辑。具体来说,我们首先获取了 requires 参数的值,然后判断当前用户是否有权限访问该字段,最后调用原始解析器来获取字段的值。

schemaDirectives 中,我们将 auth 指令的解析器注册到了 Schema 中。

最后,我们可以通过以下代码来查询 User 类型:

如果用户已经登录并且具有 USER 角色,那么将返回 nameemail 字段的值。否则,将抛出 Authentication required 异常。

总结

通过使用 Schema Directive,我们可以实现更细粒度的控制,从而提高 API 的安全性和可维护性。在实际开发中,我们可以根据具体需求来定义自定义指令,并在解析器中实现相应的逻辑。

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

纠错
反馈