hotchocolate-best-practices について
hotchocolate-best-practices は、.NETでHotChocolate GraphQLサーバーを実装・レビューするためのガイダンススキルです。対象はバージョン16.6以降で、属性ベースのC#実装、ソース生成DataLoader、カーソルページングを扱います。
主な機能
- 01属性ベースのC#スキーマ実装
- 02データアクセス用のソース生成DataLoader
- 03QueryContextに基づくプロジェクション
- 04決定的な順序付けによるカーソルページング
- 05リゾルバー、ミューテーション、フィルター、ソートの指針
活用シーン
- 01N+1クエリを避けるリゾルバーの実装
- 02DataLoaderによるルート検索の一括処理
- 03順序付きカーソルページングフィールドの構築
- 04HotChocolate 16.6以降のサーバー設定とコードのレビュー
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ chillicream/ agent-skills --skill hotchocolate-best-practicesインストール後、Claude Code で/hotchocolate-best-practicesを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/dataloaders.mdfiltering.mdmutations.mdpagination.mdresolvers.mdserver-setup.mdsorting.mdsubgraph.md詳細
HotChocolate のベストプラクティス
.NET で HotChocolate GraphQL サーバーを実装またはレビューしています。すべてのガイダンスは HotChocolate 16.6 以降を対象としています。移行ガイドを確認せずに、v15 以前のコードベースに適用しないでください。このスキルでは、ChilliCream が期待するコードの書き方を定義します。実装(リゾルバー、データアクセス、DataLoader、ページネーション)を扱います。スキーマの設計(SDL の形、命名、null 許容性)は関連スキル graphql-schema-design の対象です。設計と実装の両方に関わるタスクでは、両方を使用してください。
基本原則
-
実装を優先します。
[QueryType]、[MutationType]、[ObjectType<T>]、[DataLoader]などの属性を使った静的リゾルバークラスで、通常の C# を記述し、HotChocolate にスキーマを推論させます。スキーマファーストの SDL バインディングは使わず、属性では表現できない場合に限り、ディスクリプターやConfigureによるオーバーライドを使用してください。 -
すべてのデータアクセスは DataLoader を経由します。 リレーションのリゾルバー(データを取得するルート以外のフィールド)は、
DbContextやリポジトリに直接クエリしてはいけません。DataLoader を呼び出してください。直接クエリすると N+1 のロードが発生し、リクエストスコープのキャッシュも迂回します。 -
トップレベルの
byIdフィールドでも DataLoader を使用します。 ルートの検索もバッチ処理できます。クライアントは、1 つのオペレーション内ではフィールドエイリアスを使って、複数のオペレーション間ではリクエスト/変数のバッチ処理を使って、検索をまとめられます。データベースを直接呼び出すルートリゾルバーでは、この一括処理の機会を逃します。 -
DataLoader はソース生成します。
[DataLoader]を付けた静的メソッドを記述してください。BatchDataLoader/GroupedDataLoaderを継承するクラスを手作業で記述してはいけません。ジェネレーターがクラス、インターフェイス、登録処理を生成します。 -
プロジェクションは
QueryContext<T>を経由します。 すべての DataLoader はQueryContext<TValue>パラメーターを受け取り、利用側が選択内容をデータベースまで渡せるようにします。また、キーが絞り込み後も残るように、必ずキーをプロジェクションに含めます(query.Include(x => x.Id))。一方で、親のプロパティを読み取るすべてのリゾルバーは、[Parent(requires: nameof(...))]を使って必要なプロパティを宣言し、プロジェクションでそのフィールドが利用可能な状態を維持してください。 -
ページネーションはカーソルベースで、順序が定義されています。 ページネーション対象のフィールドでは
PagingArgumentsとToPageAsync/ToBatchPageAsyncを使用します。ページネーションを行うすべてのクエリには、キーで終わる決定的な順序が必要です。ルート以外の型でのページネーションは、バッチページネーション用 DataLoader を経由させてください。オフセットページネーションは使用しないでください。相対カーソルでページへの直接移動に対応できます。
プロジェクトのセットアップ
すべての HotChocolate プロジェクトでは、ソースジェネレーターをアナライザー専用パッケージとして参照し、モジュール名を明示します。
<PackageReference Include="HotChocolate.AspNetCore" />
<PackageReference Include="HotChocolate.Data" />
<PackageReference Include="HotChocolate.Types.Analyzers">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Properties/ModuleInfo.cs には、ドメイン名にちなんだモジュール名を記述する 1 行を記載します。アセンブリ名から導出される既定値には決して頼らないでください。
[assembly: Module("RecommendationTypes")]
これにより、プロジェクトの GraphQL 関連の型(型と DataLoader の両方)をすべて登録する生成メソッドの名前が指定されます。一般的なサーバー設定は共有の AddDefaultSettings 拡張にまとめ、メインのチェーンにはスキーマ固有の選択だけが示されるようにしてください。詳しくは references/server-setup.md を参照してください。
builder
.AddGraphQL()
.AddDefaultSettings()
.AddRecommendationTypes();
リファレンスファイル一覧
実例を交えた、詳細なルールです。現在のタスクに関係するものだけを読み込んでください。
| リファレンス | 読み込むタイミング |
|---|---|
| references/dataloaders.md | DataLoader、データを取得するリゾルバー、N+1 の懸念、byId フィールドのいずれかを扱う場合 |
| references/pagination.md | ページネーション対象のフィールド、[UseConnection]、PagingArguments、コネクション/ページ型、コレクションのソートを扱う場合 |
| references/resolvers.md | [ObjectType<T>]、[BindMember]、[Parent(requires:)] を使ったエンティティの拡張、ルート型クラス、フィールド名を扱う場合 |
| references/subgraph.md | プロジェクトがサブグラフである場合。ビルダーチェーンにある .AddSourceSchemaDefaults() または schema-settings.json ファイルで判定してください。byId フィールドの [Lookup]、エンティティ参照、コスト制限、ルックアップとしてのノードについて説明しています |
| references/server-setup.md | 新しいプロジェクト、Program.cs/ビルダーチェーン、csproj パッケージ、[assembly: Module]、AddDefaultSettings を扱う場合 |
| references/mutations.md | ミューテーション、[MutationType]、ミューテーション規約、[Error]、ペイロード/入力の形状を扱う場合 |
| references/filtering.md | UseFiltering の使用、フィルター入力型、フィールドをフィルター可能にするかどうかの判断を扱う場合 |
| references/sorting.md | UseSorting の使用、ソート入力型、フィールドをクライアント側でソート可能にするかどうかの判断を扱う場合 |
このスキルの成長に合わせて、リファレンスを追加していきます。