请求概述
以下内容故意简化了 Grafast 的内部工作原理,重点关注单负载 GraphQL 请求,而不是返回流的请求。其目的是让您对系统的工作原理有一个大致了解。
对于一个简单的 GraphQL 请求(一个不返回流的请求),请求周期看起来像这样
- 接收并解析来自用户的请求
- 查找或构建操作和输出计划
- 执行操作和输出计划
- 将数据返回给用户
接收并解析请求
本质上与 graphql-js 系统相同,只是我们对文档解析进行了缓存。
获取操作计划
当 Grafast 首次看到一个操作时,它会构建一个 操作计划。在构建操作计划时,它可能还确定了未来请求必须满足的特定约束,以便使用相同的操作计划;例如,如果请求包含 @skip(if: $variable)
,则根据 $variable
是 true
还是 false
,需要不同的操作计划。在可能的情况下,约束尽可能窄 - 例如,"变量 $foo 是一个列表" 比 "变量 $foo 是列表 [1,2,3]" 更可取 - 以最大限度地重复使用。
当将来再次看到一个操作时,Grafast 会寻找一个现有操作计划,其约束适合该请求。如果存在,则可以执行此操作计划,否则将创建一个新的操作计划(参见上一段)。
执行操作计划
Grafast 将使用变量、上下文值、根值等填充计划中相关的系统步骤,然后执行执行计划,执行流程从执行计划的步骤图向下流动,每个步骤只执行一次(有时与其他步骤并行),直到所有步骤都执行完毕。由于每个步骤在每个请求中只执行一次,因此执行必须批处理所有数据。因此,它从每个依赖项接收一个数据列表,并且必须返回一个相应的数据列表,以便其依赖项可以自行使用。
执行计划执行完成后,收集到的值将通过输出计划生成输出。通常情况下,这是一个 JSON 对象,但是为了优化,Grafast 可以选择输出字符串化的 JSON,而无需构建中间 JavaScript 对象。
当操作涉及流时,相关的执行和输出计划步骤将针对流的每个元素执行。
将数据返回给用户
这与 graphql-js 项目中的相同,但 Grafast 还支持一种优化的字符串化结果策略,如果您需要这样做(例如,如果您通过 HTTP 提供服务)。因此,我们建议您在将结果发送给用户之前使用 stringifyPayload
而不是 JSON.stringify
。
import { stringifyPayload, grafast } from "grafast";
const result = await grafast(/*...*/);
console.log(stringifyPayload(result));