GraphQL 是一种用于构建 API 的查询语言,其具有强大的类型系统和灵活的查询语法。通过使用 GraphQL,我们可以轻松地定义和查询数据模型,而不必担心与后端 API 的交互细节。
然而,在实际开发中,我们可能需要更细粒度的控制来保证 API 的安全性和可维护性。这时候,Schema Directive 就成为了一个非常有用的工具。
Schema Directive 概述
Schema Directive 是 GraphQL 中的一种元数据,它可以用来在 Schema 中为字段或类型添加额外的元数据。在使用 Schema Directive 时,我们可以通过自定义指令来实现对查询、变量、字段等细粒度的控制。
Schema Directive 的定义方式如下:
directive @directiveName(argumentName: ArgumentType) on EXECUTABLE_LOCATION
其中,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
的参数,其默认值为 USER
。User
类型中的 email
字段上使用了 @auth(requires: USER)
,表示只有 USER
角色的用户才能查看该字段。
下面,我们需要在解析器中实现 @auth
指令的逻辑。这里我们使用了 graphql-tools
库来实现自定义指令的解析器:
-- -------------------- ---- ------- ----- - --------------------- ---- ---------------------- - - ------------------------- ----- - -------------------- - - ------------------- ----- ------------- ------- ---------------------- - --------------------------- - ----- - -------- - - ---------- ----- ---------------- - ------------- -- --------------------- ------------- - -------- --------- - ----- -- - -------- - ----- -- --------------- - ----- --- --------------------- ----------- - -- --------- --- ------- -- ----------------- --- -------- - ----- --- -------------------- ----------- - ------ ---------------------------- ------ -- - - ----- -------- - ---- --------- --------------- ---- - ----- -- ---------------- ---- ---- - ----- ---- - ---- ---- - ----- ------- ------ ------- --------------- ----- - ---- ----- - --- ----- - -- ----- --------- - - ------ - --- -------- ----- -------- -- - ------ ------------- -- -- ----- - ----- -------- -- - ------ ------------ -- ------ -------- -- - ------ ------------- -- -- -- ----- ------ - ---------------------- --------- ---------- ----------------- - ----- -------------- -- ---
在上述代码中,我们定义了一个 AuthDirective
类,并通过 visitFieldDefinition
方法实现了 @auth
指令的逻辑。具体来说,我们首先获取了 requires
参数的值,然后判断当前用户是否有权限访问该字段,最后调用原始解析器来获取字段的值。
在 schemaDirectives
中,我们将 auth
指令的解析器注册到了 Schema 中。
最后,我们可以通过以下代码来查询 User 类型:
query { me { name email } }
如果用户已经登录并且具有 USER
角色,那么将返回 name
和 email
字段的值。否则,将抛出 Authentication required
异常。
总结
通过使用 Schema Directive,我们可以实现更细粒度的控制,从而提高 API 的安全性和可维护性。在实际开发中,我们可以根据具体需求来定义自定义指令,并在解析器中实现相应的逻辑。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6513baa595b1f8cacdc29b97