如何使用 GraphQL 和 ApolloStack 解析 union/interface 字段
How to resolve union/interface fields with GraphQL and ApolloStack
我正在使用我的 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 中可行吗?必须有更好的方法来实现这一点,因为这是一个很常见的用例。
理想情况下,我希望能够在我的解析器中知道我的查询要求哪些片段,因此我只能调用所要求的端点(每个片段一个端点)。
{
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, but it ONLY includes the interface type, which I found confusing. I have an additional complete runnable example of Union types (configured identically to interfaces) available here
我正在使用我的 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 中可行吗?必须有更好的方法来实现这一点,因为这是一个很常见的用例。
理想情况下,我希望能够在我的解析器中知道我的查询要求哪些片段,因此我只能调用所要求的端点(每个片段一个端点)。
{
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, but it ONLY includes the interface type, which I found confusing. I have an additional complete runnable example of Union types (configured identically to interfaces) available here