如何构建可扩展的 GraphQL 架构

GraphQL 是一种由 Facebook 开发的查询语言,用于开发 API。GraphQL 的优点在于它允许您指定需要的数据,并使多个请求合并为一个请求。这使得 GraphQL 适用于移动应用程序,因为它可以减少网络请求次数。在本文中,我们将讨论如何构建可扩展的 GraphQL 架构。

1. 理解 GraphQL 架构

GraphQL 架构由类型和解析器组成。类型定义了查询语言中的可用字段和关系。解析器是在查询时被调用的函数,用于检索和组织数据。在 GraphQL 中,您需要定义两个类型:查询和突变。查询用于检索数据,突变用于更改数据。

例如,以下是一个简单的 GraphQL 查询:

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

在上面的查询中,我们向查询窗口添加了一个 user 字段,并传递了一个 id 参数。我们还要求 GraphQL 检索 nameemailposts 数据。

2. 设计可扩展的 GraphQL 架构

构建可扩展的 GraphQL 架构的关键是正确定义类型和解析器。定义类型时,必须考虑未来如何扩展数据模型。以下是一些有用的模式:

2.1. 将关联数据类型成为 GraphQL 类型

将关联数据类型成为 GraphQL 类型是构建可扩展 GraphQL 架构的关键。例如,假设我们有一个 Post 类型和一个 User 类型。在 User 类型中,我们添加一个 posts 字段以返回与 User 相关联的所有帖子。

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

Django 的关系模型(OneToMany, ManyToMany)或SQLAlchemy都支持关联数据的定义。

2.2. 使用接口定义类型

使用接口定义类型可以在类型层面上创建共享行为。例如,我们可以使用接口将 PostComment 类型定义为共享 idcontent 字段的类型。

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

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

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

2.3. 使用 union 类型

使用 union 类型表示不相交的类型。例如,我们可以使用 union 类型定义一个 SearchResult 类型,该类型可以包括 PostComment

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

这样,我们就可以将 SearchResult 返回到查询中,并使用类型保护(type guard)来确定它是否是 Post 还是 Comment

3. 编写 GraphQL 解析器

编写 GraphQL 解析器时,应该关注以下几点:

3.1. 使用批处理 API 来优化异步磨损

使用批处理 API 可以改善 GraphQL API 的性能。例如,使用 DataLoader 可以减少对数据库的查询次数。

3.2. 实现 RBAC

实现基于角色的访问控制 (RBAC) 可以确保未经授权的用户无法访问机密数据。根据不同上下文分离不同的角色或使用中间件或多个解析器组成 pipeline 来增强顺序控制和权限管理。

3.3. 防止 DoS 攻击

防止拒绝服务 (DoS) 攻击可以通过防止花费过多的时间对请求 Ranker 或将操作范围限制为可处理的最小数据集来实现。graphql-proteus 是一种 GraphQL API 网关,可以防止 DoS 攻击。

4. 示例代码

以下是使用 Node.js、GraphQL 和 Apollo Server 构建可扩展的 GraphQL 架构的示例代码:

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

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

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

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

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

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

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

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

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

在上面的代码中,我们定义了一个 User 类型和一个 Post 类型,并使用 Mongoose 模型来定义它们的行为。我们还定义了一个 Query 类型,它包括了 userpostposts 字段。

在解析器中,我们实现了这些字段的逻辑。我们使用 findByIdfind 方法从数据库中获取数据,并使用 asyncawait 来确保异步函数的正确执行。我们还定义了 PostUser 类型之间的关系,在 Post 类型的解析器中使用了关联数据。

结论

在本文中,我们介绍了如何构建可扩展的 GraphQL 架构。正确定义类型和解析器是构建可扩展 GraphQL 架构的关键。GraphQL 具有许多优点,但为了获得最佳性能和可扩展性,您应该牢记讨论中列出的最佳实践。

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