Graphqlインスタンスとのインタフェースを使用していますが、おそらくこの問題は共用体にも当てはまります。 インターフェイスを実装するすべてのタイプに共通する2つのフィールドがありますが、各タイプには複数の追加フィールドがあります。GraphqlとApolloStackを使った共用体/インタフェースフィールドの解決方法
は、私はタイプごとに追加のフィールドを入手するにはどうすればよい次のスキーマ
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);
}
}
}
を考えると?
現在、id
とtype
の基本フィールドを取得するために、すべての食品を取得しています。allFood
その後、私は結果をループしています。タイプがPizza
のものが見つかった場合は、fetchFromPizzaEndpoint
に呼び出しを行い、追加フィールドを取得して元の基本タイプにマージします。私はこれを各タイプごとに繰り返します。
上記のように、特定のフィールド(Pizza.toppings
など)で手動で特定のフィールドを解決することもできます。
私の解決策は理想的ではありません。単一のフィールドtoppings
と同じように、各タイプごとに複数のフィールドを解決することができます。これはGraphQLで可能ですか?これを実現するには、より良い方法が必要です。これは、一般的な使用例であるためです。
理想的には、自分のクエリで要求されているフラグメントを私のリゾルバで知ることができるようにするため、要求されるエンドポイント(1つのフラグメントあたり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);
}
}
}
各データローダーから返されるものについて詳しく説明できますか?このユースケースは私にとってはかなり外見に見えますが、サーバ実装ではいくつかのユニオンタイプのケースがあります。私たちにとっては、ユニオンに含まれているデータをDBから取り込みます(それ以上のデータをすべてロードする必要はありません)。そして、GraphQLがデータを(型リゾルバで)返すべき型を決定します。 – ephemer
DataLoadersは単にデータをフェッチするFacebook DataLoaderであり、データのソースは重要ではありません。現在、私はあなたが述べたとおりに正確にやっていますが、私が使用するよりも多くのデータを取得する必要があるため、非効率です。たとえば、「ピザ」を断片化するだけでは、「サラダ」のプロパティを下げてはいけません。フラグメントレベルリゾルバを持つことは素晴らしいことですが、GraphQL開発者と話した後、将来の機能であり、現在サポートされていないようです。 – JustinN
それは私が理解していないビットです。あなたのデータが実際にピザの場合、Saladのプロパティはどのように取得しますか?そのため、DataLoaderによって返されるデータは重要です。たとえば、MongoDBからデータをロードします。MongoDBからドキュメントをクエリすると、そのドキュメントに含まれているもの(つまり、ピザドキュメントの「ピザ」データのみ)とそれ以外は含まれません。そこに非効率的なことはありません。 GraphQLから返されるデータに非効率性があることを意味するなら、それはあなたにとって完全にユニオンタイプが扱うものです。それがあなたが心配している非効率性であるなら、私はより詳細な答えを書くでしょう – ephemer