我在GraphQL实例中使用了接口(interface),但是这个问题也许也适用于联合。
在实现接口(interface)的所有类型中都有2个公共(public)字段,但是每种类型上都有多个其他字段。
给定以下架构
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有可能吗?鉴于这是一个相当普遍的用例,因此必须有一种更好的方法来实现这一目标。理想情况下,我希望能够在解析器中知道查询所请求的片段,因此,我只能调用被请求的端点(每个片段一个端点)。
{
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的位置)
{
Query: {
GetAllFood(root) {
return fetchFromAllFoodsEndpoint()
.then((items) => {
return mergeExtraFieldsByType(items);
});
},
},
FoodType: {
__resolveType(data, ctx, info) {
return whatIsTheType(data, ctx, info)
}
}
}
官方文档中有一个示例here,但它仅包含接口(interface)类型,我感到困惑。我还有一个可用的联合类型(与接口(interface)配置相同)的完整的可运行示例,它是here