GraphQLインスタンスとのインターフェースを利用していますが、この質問はおそらくユニオンにも当てはまります。インターフェイスを実装するすべてのタイプに共通のフィールドが2つありますが、各タイプには複数の追加フィールドがあります。
次のスキーマが与えられた
interface FoodType {
id: String
type: String
}
type Pizza implements FoodType {
id: String
type: String
pizzaType: String
toppings: [String]
size: String
}
type Salad implements FoodType {
id: String
type: String
vegetarian: Boolean
dressing: Boolean
}
type BasicFood implements FoodType {
id: String
type: String
}
および次のリゾルバ
{
Query: {
GetAllFood(root) {
return fetchFromAllFoodsEndpoint()
.then((items) => {
return mergeExtraFieldsByType(items);
});
},
},
FoodType: {
__resolveType(food) {
switch (food.type) {
case 'pizza': return 'Pizza';
case 'salad': return 'Salad';
default: return 'BasicFood';
}
},
},
Pizza: {
toppings({pizzaType}) {
return fetchFromPizzaEndpoint(pizzaType);
}
}
}
タイプごとに追加のフィールドを取得するにはどうすればよいですか?
現在、allFood
とid
の基本フィールドを取得するために、すべての食品を取得するtype
があります。この後、結果をループし、タイプPizza
が見つかった場合は、fetchFromPizzaEndpoint
を呼び出して、追加のフィールドを取得し、それらを元の基本タイプにマージします。タイプごとにこれを繰り返します。
上記のように、Pizza.toppings
などのタイプの特定のフィールドを手動で解決することもできます。
今の私の解決策は理想的ではありません。単一のフィールドtoppings
で行うのとほぼ同じ方法で、タイプごとに複数のフィールドを解決できるようにしたいと思います。これはGraphQLで可能ですか?これは非常に一般的なユースケースであるため、これを実現するためのより良い方法が必要です。
理想的には、リゾルバーでクエリが要求しているフラグメントを知りたいので、要求されたエンドポイント(フラグメントごとに1つのエンドポイント)のみを呼び出すことができます。
{
Query: {
GetAllFood(root) {
return fetchFromAllFoodsEndpoint();
},
},
FoodType: {
__resolveType(food) {
switch (food.type) {
case 'pizza': return 'Pizza';
case 'salad': return 'Salad';
default: return 'BasicFood';
}
},
},
Pizza: {
__resolveMissingFields(food) {
return fetchFromPizzaEndpoint(food.id);
}
},
Salad: {
__resolveMissingFields(food) {
return fetchFromSaladEndpoint(food.id);
}
}
}
この質問は5か月前のものですが、この問題を抱えている他の人の助けになることを願っています。彼は次のような構造のリゾルバを渡します
{
Query: {
GetAllFood(root) {
return fetchFromAllFoodsEndpoint()
.then((items) => {
return mergeExtraFieldsByType(items);
});
},
},
FoodType: {
__resolveType(food) {
switch (food.type) {
case 'pizza': return 'Pizza';
case 'salad': return 'Salad';
default: return 'BasicFood';
}
},
},
Pizza: {
toppings({pizzaType}) {
return fetchFromPizzaEndpoint(pizzaType);
}
}
}
しかし、彼は本当に次のようなものを望んでいました(正確ではありませんが、クエリに対する__resolveTypeの場所を強調しています)
{
Query: {
GetAllFood(root) {
return fetchFromAllFoodsEndpoint()
.then((items) => {
return mergeExtraFieldsByType(items);
});
},
},
FoodType: {
__resolveType(data, ctx, info) {
return whatIsTheType(data, ctx, info)
}
}
}
公式ドキュメントには例があります ここ 、しかしそれは私が混乱していると思ったインターフェースタイプだけを含んでいます。利用可能なUnionタイプ(インターフェースと同じように構成されている)の追加の完全な実行可能な例があります ここ