在 GraphOS 路由器中执行操作限制
设置深度、高度、别名和根字段的约束
此功能仅在 GraphOS Enterprise计划.
中可用。您可以通过注册免费 企业试用版.
您可以在操作限制中定义您的router's 配置,以拒绝可能恶意的请求。如果一个操作超过了任何指定限制,则会被拒绝(除非您以warn_only模式运行您的 router)。(warn_only
模式运行)。
设置
要使用操作限制,您必须运行GraphOS Router 的 v1.17 或更高版本。 下载最新版本。
您需要在router 的YAML 配置文件中定义操作限制,例如:
limits:max_depth: 100max_height: 200max_aliases: 30max_root_fields: 20# Uncomment to enable warn_only mode# warn_only: true
每个限制值都是一个整数。您可以定义任何组合的支持的限制。
支持的限制
max_depth
限制操作中的选择集最深嵌套层级,包括fields(字段)在fragments(片段)中。
下面是具有深度三的GetBook
操作:
query GetBook {book { # Depth 1 (root field)...bookDetails}}fragment bookDetails on Book {details { # Depth 2 (nested under `book`)... on ProductDetailsBook {country # Depth 3 (nested under `details`)}}}
最大高度
限制在一个操作中包含的唯一 字段 数量,包括片段的字段。如果一个特定的字段通过 别名 被多次包含,则只计算 一次。
下面的 GetUser
操作的高度为三:
query GetUser {user { # 1id # 2name # 3username: name # Aliased duplicate (not counted)}}
每个唯一的 字段都会将操作的高度增加一个,无论该字段的返回类型(标量、对象或列表)。
最大别名
限制一个操作中包含的总别名字段数,包括片段的字段。
下面的 GetUser
操作包含了三个 别名:
query GetUser {user {nickname: name # 1username: name # 2handle: name # 3}}
每个别名字段都会将别名计数增加一个,无论该字段的返回类型(标量、对象或列表)。
最大根字段
限制一个操作中根字段的数量,包括片段中的根字段。如果一个特定的根字段通过 别名 被多次包含,每个使用都计为一次。
以下操作包括三个根字段:
query GetTopProducts {topBooks { # 1id}topMovies { # 2id}topGames { # 3id}}
warn_only
模式
如果你以 warn_only
模式运行路由器,则超过定义的限值的 不 被拒绝。相反,路由器会像平常一样处理这些操作,并发出一条 WARN
跟踪,记录所有超过的限值,如下所示:
2023-03-15T19:08:23.123456Z WARN apollo_router::operation_limits: max_depth exceeded, max_depth: 3, current_op_depth: 5, operation: "query GetOwnerLocation {cat {owner {location {postalCode}}}}"
在测试期间以 warn_only
模式运行可能有助于确定为你 supergraph 设置的最合适的限值。
您可以为您的路由器启用或禁用 warn_only
模式,这在您的路由器's YAML 配置文件中,如下所示:
limits:warn_only: true # warn_only mode always enabled
超出限制的响应格式
每当您的路由器因为超过操作限制而拒绝请求时,路由器会以 400 HTTP 状态码和一个标准的 GraphQL 错误响应体进行响应:
# HTTP 400{"data": {},"errors": [{"message": "Maximum height (field count) limit exceeded in this operation","extensions": {"code": "MAX_HEIGHT_LIMIT"}}]}
如果您在 warn_only
模式 下运行您的路由器,则