メインコンテンツまでスキップ

GraphQL API の高度なクエリ

Strapi の GraphQL API は多くのクエリを自動解決しますが、複雑なデータ取得ではリレーションを深く辿ったり、リゾルバを連鎖させたりする必要があります。ここではそのようなケースの扱い方を簡潔に説明します。

詳しくは GraphQL のカスタマイズ を参照してください。

複数階層のクエリ

ネストしたセレクションセットで、リレーションを何階層でも取得できます。

{
restaurants {
documentId
name
categories {
documentId
name
parent {
documentId
name
}
}
}
}

GraphQL プラグインはネストしたリレーションを自動で解決します。特定の階層だけ独自ロジックを入れたい場合は、そのフィールド用のカスタムリゾルバを定義します。

リゾルバの連鎖

カスタムリゾルバから別のリゾルバを呼び出し、既存の処理を再利用できます。親リゾルバで権限やコンテキストを解決し、子リゾルバに渡すパターンがよく使われます。

/src/api/restaurant/resolvers/restaurant.ts
export default {
Query: {
restaurants: async (parent, args, ctx) => {
const documents = await strapi.documents('api::restaurant.restaurant').findMany(args);
return documents.map(doc => ctx.request.graphql.resolve('Restaurant', doc));
},
},
};

この例では親リゾルバが Document Service API でレストランを取得し、プラグインが生成した Restaurant リゾルバに委譲して、フィールド選択など既定の挙動を維持しています。

集計のドリルダウン

Relay 形式のコネクションには aggregate フィールドがあります。全体の指標を出しつつ、グループごとに詳細を見せる用途に使えます。groupBy とページネーション変数を組み合わせてレスポンスを小さく保てます。

query RestaurantsByCity($first: Int, $after: String) {
restaurants_connection(pagination: { limit: $first, start: $after }) {
aggregate {
groupBy {
city {
key
connection(pagination: { limit: 5 }) {
aggregate {
count
}
nodes {
documentId
name
}
}
}
}
}
}
}

クエリ変数でネストしたページネーションを調整します。集計はサーバー側で行われるため、クライアントは必要なサマリー行だけ受け取れ、データセットが大きくてもダッシュボードを軽く保てます。