GraphQL 是一种由 Facebook 开发的查询语言,用于开发 API。GraphQL 的优点在于它允许您指定需要的数据,并使多个请求合并为一个请求。这使得 GraphQL 适用于移动应用程序,因为它可以减少网络请求次数。在本文中,我们将讨论如何构建可扩展的 GraphQL 架构。
1. 理解 GraphQL 架构
GraphQL 架构由类型和解析器组成。类型定义了查询语言中的可用字段和关系。解析器是在查询时被调用的函数,用于检索和组织数据。在 GraphQL 中,您需要定义两个类型:查询和突变。查询用于检索数据,突变用于更改数据。
例如,以下是一个简单的 GraphQL 查询:
- -------- ---- - ---- ----- ----- - ----- ---- - - -
在上面的查询中,我们向查询窗口添加了一个 user
字段,并传递了一个 id
参数。我们还要求 GraphQL 检索 name
,email
和 posts
数据。
2. 设计可扩展的 GraphQL 架构
构建可扩展的 GraphQL 架构的关键是正确定义类型和解析器。定义类型时,必须考虑未来如何扩展数据模型。以下是一些有用的模式:
2.1. 将关联数据类型成为 GraphQL 类型
将关联数据类型成为 GraphQL 类型是构建可扩展 GraphQL 架构的关键。例如,假设我们有一个 Post
类型和一个 User
类型。在 User
类型中,我们添加一个 posts
字段以返回与 User
相关联的所有帖子。
---- ---- - --- --- ----- ------ ------ ------ ------ -------- -
Django 的关系模型(OneToMany, ManyToMany)或SQLAlchemy都支持关联数据的定义。
2.2. 使用接口定义类型
使用接口定义类型可以在类型层面上创建共享行为。例如,我们可以使用接口将 Post
和 Comment
类型定义为共享 id
和 content
字段的类型。
--------- ---- - --- --- - ---- ---- ---------- ---- - --- --- ------ ------ ----- ------ - ---- ------- ---------- ---- - --- --- -------- ------ -
2.3. 使用 union 类型
使用 union 类型表示不相交的类型。例如,我们可以使用 union 类型定义一个 SearchResult
类型,该类型可以包括 Post
和 Comment
。
----- ------------ - ---- - -------
这样,我们就可以将 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
类型,它包括了 user
,post
和 posts
字段。
在解析器中,我们实现了这些字段的逻辑。我们使用 findById
和 find
方法从数据库中获取数据,并使用 async
和 await
来确保异步函数的正确执行。我们还定义了 Post
和 User
类型之间的关系,在 Post
类型的解析器中使用了关联数据。
结论
在本文中,我们介绍了如何构建可扩展的 GraphQL 架构。正确定义类型和解析器是构建可扩展 GraphQL 架构的关键。GraphQL 具有许多优点,但为了获得最佳性能和可扩展性,您应该牢记讨论中列出的最佳实践。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/67036b25d91dce0dc84b777c