跳到主要内容

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 配置。