Azure / Azure/data-api-builder

[Bug]: 2.0 rejects filter-variable queries with HC0047; Hot Chocolate cost limits are not configurable

オープン
#3,748 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る
cri graphql
主要言語
C#
スター
1.5k
フォーク
370
平均マージ
3日 22時間
マージ済み PR(30日)
9

説明

# [Bug]: 2.0 GA rejects `filter: $variable` queries with HC0047 — cost limits are not configurable

## What happened?

After upgrading from 1.7.93 to 2.0.8, every query that passes a whole filter input as a GraphQL variable fails with:

```json
{
"errors": [{
"message": "The maximum allowed field cost was exceeded.",
"extensions": { "code": "HC0047", "fieldCost": 1325, "maxFieldCost": 1000 }
}]
}
```

Hot Chocolate 16 (bundled since 2.0) enables static cost analysis by default with `MaxFieldCost = 1000`, and DAB exposes **no configuration** for it — `runtime.graphql` only has `depth-limit`; `ModifyCostOptions` is never called in `Startup.AddGraphQLService`.

## Why this breaks virtually every real client

Generated `*FilterInput` types are self-referential (`and: [XFilterInput!]`, `or: [XFilterInput!]`). When a filter is supplied as a variable, the cost analyzer prices the input type's **recursive worst case**, not the actual value. Measured against a DAB 2.0.8 instance (MSSQL, 131 entities) using `GraphQL-Cost: validate`:

| query shape | fieldCost |
|---|---|
| `organizations(first: 20) { items { id } }` | 30 |
| same + inline literal filter `{status: {name: {in: [$name]}}}` | 33 |
| same + `filter: $f` variable (**no value even supplied**) | **1243** |

The ~1200 floor is entity-independent — a 3-column lookup table's filter variable prices at ~1202 — so **every** `filter: $variable` query exceeds the 1000 default. In our app that's 79 call sites across 48 routes, i.e. every list page. `filter: $variable` is the natural pattern for dynamic filtering (and what most GraphQL client codegen produces), and it worked on 1.x.

Related upstream: ChilliCream/graphql-platform#9548 (cost assumes two levels of recursion for circular references).

## Expected

Either (preferably both):
1. `runtime.graphql` config for cost analysis — e.g. `cost: { enforce: bool, max-field-cost: int, max-type-cost: int }` — mirroring the existing `depth-limit` knob.
2. Defaults that don't reject variable-supplied filters on every entity (e.g. enforcement off unless configured, or variable inputs priced by provided value rather than recursive worst case).

## Steps to reproduce

1. `dab init` against any MSSQL database, add any table entity, start DAB 2.0.8.
2. `POST /graphql` with `query Q($f: FilterInput) { (filter: $f) { items { __typename } } }` and any (or no) variable value.
3. Observe HC0047 with fieldCost ≈ 1200+ vs maxFieldCost 1000.

## Version

2.0.8 (the v2.0.9 tag contains no cost-related changes, so it is equally affected)

## What database are you using?

Azure SQL / SQL Server

## What hosting model are you using?

Container (App Service)

コントリビューションガイド

コントリビューションガイドを開く

調査の方向性

ModifyCostOptions が呼び出されていないと報告されている Startup.AddGraphQLService から始め、既存の depth-limit 設定に対する runtime.graphql の処理を調べます。dab init の後に、フィルター変数を使用するクエリを /graphql に POST して問題を再現し、その後、コストの動作を構成可能であること、および変数から提供された有効なフィルターが HC0047 で予期せず失敗しなくなっていることを確認します。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
csharp, graphql
領域
api, backend
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
静か
明瞭さ
おおむね明確
初心者へのやさしさ
48/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。