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