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

标题传播

配置将 HTTP 标题传播到子图


您可以为或 Apollo 路由核心包含在其向每个子图发出的请求中。。您可以定义针对每个子图的标题规则,以及适用于所有子图的规则。

您在您的YAML 配置文件中定义标题规则,如下所示:

router.yaml
# ...other configuration...
headers:
all: # Header rules for all subgraphs
request:
- propagate:
matching: ^upstream-header-.*
- remove:
named: "x-legacy-account-id"
subgraphs:
products: # Header rules for just the products subgraph
request:
- insert:
name: "router-subgraph-name"
value: "products"

支持的标题规则

支持以下类型的标题规则:

传播

允许您有选择地传递客户端请求中包含的标题到路由器。

您可以根据匹配的正则表达式模式来指定要传播哪些标题:

- propagate:
matching: .*

注意

在通过模式传播时,路由器从未传播所谓的端到端头(如Content-Length)。

或者,您可以通过named选项提供一个静态字符串。named配置具有额外的灵活性,因为它们支持以下选项:

  • default:若客户端未发送值,则设置该值
  • rename:将头部键重命名为提供的值
- propagate:
named: "x-user-id"
default: "abc123"
rename: "account-id"

remove

选择性删除客户端发往的请求中包含的头部。与propagate类似,此选项可以匹配静态字符串或正则表达式

# Do not send this subgraph the "Cookie" header.
- remove:
named: "Cookie"
- remove:
# Remove headers that include the legacy 'x-' prefix.
matching: ^x-.*$

insert

允许您向发往特定的请求添加自定义头部。这些头部是字符串(静态的、来自请求数据包或上下文),它们来自,而不是来自客户端。

  • 插入静态头部
- insert:
name: "sent-from-our-apollo-router"
value: "indeed"
  • 从上下文插入头部
- insert:
name: "sent-from-our-apollo-router-context"
from_context: "my_key_in_context"
  • 从请求数据包中插入头部
- insert:
name: "sent-from-our-apollo-router-request-body"
path: ".operationName" # It's a JSON path query to fetch the operation name from request body
default: "UNKNOWN" # If no operationName has been specified

示例JSON路径查询

假设您有一个以下结构的JSON请求数据包

{
"query": "{ products { id name } }",
"extensions": {
"metadata": [
{
"app_name": "random_app_name"
}
]
}
}

要获取 app_name的值,对应的路径是.extensions.metadata[0].app_name

JSON路径查询始终以点.开始

使用此配置

headers:
all:
request:
- insert:
name: from_app_name
path: .extensions.metadata[0].app_name

您将为所有子图传递一个头部:"from_app_name": "random_app_name"

规则顺序

头部规则按其声明的顺序应用,后来的规则可以覆盖较早规则的效果。考虑以下示例:

bad_configuration.yaml
headers:
all:
request:
- remove:
named: "test"
- propagate:
matching: .*

在此示例中,首先从传播列表中移除任何名为test的头部。然而,传播头部的列表当前为空!接下来,propagate规则会把所有头部添加到传播列表中,包括test

要正确地从传播列表中删除头部,请确保将您的remove规则定义在任何propagate规则之后:

good_configuration.yaml
headers:
all:
request:
- propagate:
matching: .*
- remove:
named: "test"

使用此排序,首先将所有头部添加到传播列表,接着从列表中移除test头部。

示例

以下是一个包含所有可能配置选项的完整示例

router.yaml
headers:
# Header rules for all subgraphs
all:
request:
# Propagate matching headers
- propagate:
matching: ^upstream-header-.*
# Propagate matching headers
- propagate:
named: "some-header"
default: "default-value"
rename: "destination-header"
# Remove the "x-legacy-account-id" header
- remove:
named: "x-legacy-account-id"
# Remove matching headers
- remove:
matching: ^x-deprecated-.*
# Insert the 'my-company' header
- insert:
name: "my-company"
value: "acme"
# Subgraph-specific header rules
subgraphs:
products:
request:
# Calls to the products subgraph have the "router-subgraph-name" header set to `products`.
- insert:
name: "router-subgraph-name"
value: "products"
accounts:
request:
# Calls to the accounts subgraph have the "router-subgraph-name" header set to `accounts`.
- insert:
name: "router-subgraph-name"
value: "accounts"

响应头传播

目前无法仅使用YAML配置从子图传播响应头到客户端。然而,您可以使用Rhai脚本实现这一点。

这种方法依赖于每个请求都有一个context对象,可以在此请求期间存储数据:

  1. 对于每个子图响应,将头部值复制到上下文中。
  2. 对于响应,将上下文中的头部值复制到响应上。

以下是使用了Rhai脚本的router.yaml示例:

router.yaml
rhai:
main: "main.rhai"

以下是收集来自子图的set-cookie头部并将它们合并到单个客户端响应头部的Rhai脚本示例:

./rhai/main.rhai
fn supergraph_service(service) {
let add_cookies_to_response = |response| {
if response.context["set_cookie_headers"]?.len > 0 {
response.headers["set-cookie"] = response.context["set_cookie_headers"];
}
};
service.map_response(add_cookies_to_response);
}
fn subgraph_service(service, subgraph) {
let store_cookies_from_subgraphs = |response| {
if "set-cookie" in response.headers {
if response.context["set_cookie_headers"] == () {
response.context.set_cookie_headers = []
}
response.context.set_cookie_headers += response.headers.values("set-cookie");
}
};
service.map_response(store_cookies_from_subgraphs);
}

注意

如果您需要一个基于配置的解决方案来传播响应头,请在我们的问题跟踪器上留言

子图间的传播

目前无法仅使用YAML配置在子图之间传播头部。然而,您可以使用Rhai脚本实现这一点。

这种方法依赖于每个请求都有一个context对象,可以在此请求期间存储数据:

  1. 对于每个子图响应,将头部值复制到上下文中。
  2. 对于每个子图请求,将上下文中的头部值复制入子图请求。

以下是使用了Rhai脚本的router.yaml示例:

router.yaml
rhai:
main: "main.rhai"

以下是复制request-iduser头部的Rhai脚本示例:

./rhai/main.rhai
fn subgraph_service(service, subgraph) {
// The list of headers that you which to propagate.
let headers = ["request-id", "user"];
// Callback for subgraph requests. Inserts headers from context into the subgraph request.
let request_callback = |request| {
for key in headers {
if request.context[key] != () {
request.subgraph.headers[key] = request.context[key];
}
}
};
// Callback for subgraph responses. Pulls header values out of the response and inserts them into context.
let response_callback = |response| {
for key in headers {
if key in response.headers {
response.context[key] = response.headers[key];
}
}
};
// Register the callbacks.
service.map_request(request_callback);
service.map_response(response_callback);
}
上一页
子图错误包括
下一页
流量整形
评分文章评分在GitHub上编辑编辑论坛Discord

©2024Apollo Graph Inc.,商业名为Apollo GraphQL。

隐私政策

公司