请于10月8日至10日加入我们在纽约市的聚会,了解有关GraphQL Federation和API平台工程的最新技巧、趋势和新闻。加入2024年纽约市的GraphQL峰会
文档
免费开始

路由自定义

通过自定义功能扩展你的路由器


您可以为以下路由器创建自定义配置以添加通过内置功能不可用的功能: 或者配置选项。例如,您可以针对每个传入请求进行外部调用以获取身份验证数据。

自定义类型

GraphOS 路由器支持以下自定义类型:

  • Rhai 脚本
    • Rhai 脚本语言 允许您通过挂钩路由器请求生命周期的不同阶段,直接将功能添加到您的原版 静态二进制文件。
  • 外部协同处理企业功能
    • 如果您组织拥有 GraphOS 企业计划,则您可以使用任何语言编写自定义请求处理代码。此代码可以与您的 路由器 或分开运行。
    • 路由器通过 HTTP 调用您的自定义代码,并发送每个传入客户端请求的详细信息。

Apollo 路由器核心仅通过 Rhai 脚本 支持自定义。

由于 Rhai 脚本 更易于部署,如果您的情况需要使用它们,则建议使用它们。如果您的自定义需要执行以下任何操作(这些操作 Rhai 脚本不支持),请使用外部协同处理:

  • 读取或写入磁盘
  • 执行网络请求
  • 使用特定语言或框架的库

请求生命周期

自定义在请求生命周期的特定点上介入,具体取决于您要执行的任务。每个点都由一个具有其自己的请求和响应对象的自定义服务表示。

request
request
response
response
Your infrastructure
subgraph A
subgraph B
subgraph C
Router
request
request
request
response
response
response
Router
Service
Supergraph
Service
Execution
Service
Subgraph
Service
Client

每个服务都可以有一组插件。对于请求,路由器在服务之前执行插件。

Service
request
request
request
request
Core
service
Plugin 2
Plugin 1
Client
Next service

对于响应,路由器在服务之后执行插件。

Service
response
response
response
response
Plugin 1
Plugin 2
Core
service
Client
Next service

每个请求和响应对象都包含一个上下文对象,它在整个过程中都会传递。每个请求的上下文对象是唯一的。您可以使用它来在请求和响应之间存储特定于插件的零食息或用于在不同钩点之间通信。(插件可以在请求生命周期中的多个步骤中被调用。)

以下流程图展示了整个请求生命周期。第一个说明了从客户端到路由器各个部分,再到您的的请求路径。第二个说明了从您的子图返回客户端的响应路径。

请求路径

Router
Subgraph Services
1. HTTP request
2. RouterRequest
3. SupergraphRequest
4. Query
5. Query plan
6. ExecutionRequest
7a. SubgraphRequest
7b. SubgraphRequest
8a. HTTP request
8b. HTTP request
HTTP server
Router Service
Router plugins
Execution Service
Execution plugins
Subgraph Service A
Subgraph plugins
Subgraph Service B
Subgraph plugins
Supergraph Service
Supergraph plugins
Query Planner
Client
Subgraph A
Subgraph B

  1. 路由器在HTTP服务器上接收客户端请求。
  2. HTTP服务器将HTTP请求转换为一个包含HTTP头部和字节序列流的请求体RouterRequest
  3. 路由器服务接收到RouterRequest。它处理自动持久查询(),解析来自JSON的GraphQL请求,并以SupergraphRequest将结果传递给supergraph服务。
  4. supergraph服务用SupergraphRequest中的GraphQL查询调用查询规划器。
  5. 查询规划器返回一个可高效执行查询的查询计划。
  6. supergraph服务使用由SupergraphRequest和查询计划组成的ExecutionRequest调用执行服务。
  7. 对于查询计划中的每个提取节点,执行服务创建一个SubgraphRequest,然后调用相应的子图服务。
  8. 每个子图都有自己的子图服务,并且每个服务都可以有自己的子图插件配置。子图服务将SubgraphRequest转换为其子图的HTTP请求。该SubgraphRequest包含以下内容:
    • 只读SupergraphRequest
    • HTTP头部
    • 子图请求的操作类型(
    • 作为请求体的GraphQL请求对象

当您的子图提供响应后,响应将遵循以下路径。

响应路径

Subgraph Services
14. HTTP response
9a. HTTP response
9b. HTTP response
10a. SubgraphResponse
10b. SubgraphResponse
11. ExecutionResponse
12. SupergraphResponse
13. RouterResponse
HTTP server
Router Service
Router plugins
Execution Service
Execution plugins
Subgraph Service A
Subgraph plugins
Subgraph Service B
Subgraph plugins
Supergraph Service
Supergraph plugins
QueryPlanner
Client
Subgraph A
Subgraph B

  1. 每个子图为子图服务提供一个HTTP响应。
  2. 每个子图服务创建一个SubgraphResponse,包含HTTP头和一个GraphQL响应。
  3. 一旦执行服务收到所有的子图响应,它会格式化GraphQL响应 —— 移除不需要的数据并传播空值 —— 然后将它作为ExecutionResponse发送回supergraph插件。
  4. The SupergraphResponse具有与ExecutionResponse相同的内容。它包含头部和一个GraphQL响应流。这个流通常只包含一个元素(对于大多数查询而言)——如果查询使用了@defer指令或订阅,它可能包含更多元素。
  5. 路由服务接受SupergraphResponse并将GraphQL响应序列化为JSON。
  6. The HTTP服务器将JSON作为HTTP响应发送给客户端。

请求和响应细节

出于简化的目的,先前的图示分别且顺序地显示了请求和响应两侧。实际上,一些请求和响应可能会同时且重复发生。

例如,SubgraphRequest可以既并行也可以顺序地进行:一个子图的响应可能对另一个的SubgraphRequest是必要的。(查询计划器决定哪些请求可以并行执行,哪些需要顺序执行。)

并行执行请求

Subgraph Services
1A. SubgraphRequest
1B. SubgraphRequest
4A. SubgraphResponse
4B. SubgraphResponse
2A. HTTP request
2B. HTTP request
3A. HTTP response
3B. HTTP response
Execution Service
Execution plugins
Subgraph Service A
Subgraph plugins
Subgraph Service B
Subgraph plugins
Subgraph A
Subgraph B

顺序执行请求

Subgraph Services
1. SubgraphRequest
4. SubgraphResponse
5. SubgraphRequest
8. SubgraphResponse
2. HTTP request
6. HTTP request
3. HTTP response
7. HTTP response
Execution Service
Execution plugins
Subgraph Service A
Subgraph plugins
Subgraph Service B
Subgraph plugins
Subgraph A
Subgraph B

此外,一些请求和响应可能会针对同一操作重复发生多次。例如,在使用订阅的情况下,子图会在数据更新时发送新的SubgraphResponse。每个响应对象将穿过响应路径中的所有服务,并与你创建的任何自定义操作交互。

请求和响应缓冲

为了在流上正确执行并提供高性能,以下期望必须满足:

  • 请求路径: 在router_service处理步骤之后不进行缓冲
  • 响应路径: 不进行缓冲

一般来说,最好尽可能避免缓冲。如果需要的话,在router_service步骤完成后在请求路径上进行缓冲是可以的。

如果以下内容适用,建议这样做:

  • 修改路由器
  • 创建原生Rust插件
  • 创建自定义二进制文件

创建自定义

要了解如何连接到各种生命周期阶段,包括示例自定义,请参阅Rhai脚本外部协处理文档。

上一部分
健康检查
下一部分
Rhai脚本
评价文章评分在GitHub上编辑编辑论坛Discord

©2024Apollo Graph Inc.,以Apollo GraphQL的名义。

隐私政策

公司