我在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提取所有食物以获得idtype的基本字段。之后,我将遍历结果,如果发现任何类型为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

10-07 19:02
查看更多