GraphQL 查询成本参考
graphql-limit-count 插件为每个 GraphQL 文档分配整数成本,并将 其与配置的配额进行比较。默认度量是查询深度。对于深度无法充分反映处理工作量的场景,插件也可以根据文档请求的字段和参数进行评分。
成本策略
通过 cost_strategy 选择原始成本的计算方式:
| 策略 | 原始成本 |
|---|---|
depth | 选择集的嵌套深度。这是默认策略,并保留现有配置的行为。 |
complexity | 操作及每个所选字段的成本。每个节点贡献的成本为 (sum of its children) × mul + add;两个权重均默认为 1。 |
node_quantifier | 成本装饰中列出的 mul_arguments 参数具有可用值时,对应装饰节点的成本。乘数会传递到更深层的量化节点。如果没有节点同时具备匹配的装饰和可用参数,原始成本为 0。 |
例如,某个装饰在 mul_arguments 中列出 first,便可使用 first: 10 中的值。复杂度评分会将所有后代节点的成本乘以 10;节点量词评分则会将乘数 10 传递到更深层的量化节点。
计入配额的成本
插件会将原始成本转换为计入配额的整数成本。复杂度和节点量词的分数在缩放和向上取整前会先加上 0.01;深度策略不执行此调整。
score_factor 字段控制缩放。使用默认值 1 时,原始成本为整数 3 的查询会计入成本 4,原始成本为 0 的查询会计入成本 1。
限速器先计算并处理计入配额的成本,再应用 max_cost,因此被此阈值拒绝的查询仍可能消耗配额。被拒绝的查询会在到达上游前返回 HTTP 403。
启用配额响应头时,X-Graphql-Query-Cost 会报告计入配额的成本。
变量解析
默认启用变量解析。插件在计算成本前,会解析请求提供的值、操作声明的默认值,以及上游 Schema 中的参数默认值。
禁用 resolve_variables 后,first: $n 这样的参数会被视为不存在。如果量词值由变量提供,这可能导致成本被低估。
Schema 内省
网关需要上游 Schema,才能将成本装饰与查询匹配。每个 Worker 会在首次适用的请求到达时对服务进行内省,并在该 Worker 的生命周期内缓存 Schema。上游 Schema 更改后,请重新加载网关。
如果 Schema 在其他端点提供,请设置 introspection_endpoint。如果该端点需要凭据,请设置 introspection_headers。
路由未关联服务,或其服务没有成本装饰时,不会执行内省。在这种情况下,复杂度策略为每个节点使用默认权重,节点量词策略产生的原始成本为 0。
成本装饰
成本装饰为上游 Schema 中的指定位置分配权重。它们以 graphql_cost_decorations 存储在服务上。该服务下的所有路由共享这些装饰,修改装饰时无需编辑这些路由。
field_path 可以标识 GraphQL 类型(例如 Product)、类型及字段(例如 Product.name),或字段链(例如 Query.products.nodes):
| 字段 | 作用 |
|---|---|
add_value | 设置节点自身的成本,默认为 1。 |
mul_value | 将节点的子节点成本乘以此值。 |
add_arguments | 指定参数名,将其值加到节点自身的成本中。 |
mul_arguments | 指定参数名,用其值乘以后代节点的成本。在 node_quantifier 策略下,乘数会传递到更深层的量化节点。 |
在同一服务中,每个字段路径只能使用一次,并应串行处理并发的装饰更新,以保持其唯一性。在 APISIX 中,请通过服务的 graphql_cost_decorations Admin API 资源管理装饰,而不要通过服务请求体管理。请求及响应 Schema 请参阅 Admin API 服务参考。
控制成本计算及 Schema 内省的插件字段,请参阅 GraphQL Limit Count 配置。