GraphQL:带有标量和 InputObjectType 的 UnionType

问题描述

我有一个存储一些视频游戏的数据库。每个都有三个发布日期:一个在欧洲,另一个在美国,最后一个在日本。

我想允许我的 GraphQL API 用户根据这些日期搜索游戏。例如,为了获取在欧美发布但在日本发布的游戏的名称和发布日期,我们可以编写以下查询

{
  games(has_been_released: { eur: true,usa: true,jap: false }) {
    data {
      name
      release_date
    }
  }
}

因此,如果我们想获取所有地区发布的游戏,查询将是这样的:

{
  games(has_been_released: { eur: true,jap: true}) {
    data {
      name
      release_date
    }
  }
}

当所有布尔值都具有相同的值时,我想简化查询,以便我们可以编写以下代码

{
  games(has_been_released: true) {
    data {
      name
      release_date
    }
  }
}

为了做到这一点,我尝试了字段 has_been_released(带有 graphql-php)的类型定义:

<?PHP

$regionalizedBooleanInput = new InputObjectType([
    'name' => 'RegionalizedBooleanInput','description' => 'An object with properties "eur","usa" and "jap" as booleans','fields' => [
        'eur' => ['type' => Type::boolean(),'defaultValue' => null],'usa' => ['type' => Type::boolean(),'jap' => ['type' => Type::boolean(),]
]);

$booleanorRegionalizedBooleanInputType = new UnionType([
    'name' => 'BooleanorRegionalizedBooleanInput','description' => 'A boolean that can be different according to regions','types' => [
        Type::boolean(),$regionalizedBooleanInput,],'resolveType' => function($value) use ($regionalizedBooleanInput) {
        if ($value->type === 'boolean') {
            return Type::boolean();
        }
                
        return $regionalizedBooleanInput;
    },]);

但是当我这样做时,GraphiQL 会抛出此错误

错误:内省必须为可能的类型提供对象类型。 在不变(chrome-extension://fkkiamalmpiidkljmicmjfbieiclmeij/dist/chromeiql.js:14605:11) 在 getobjectType (chrome-extension://fkkiamalmpiidkljmicmjfbieiclmeij/dist/chromeiql.js:72489:80) 在 Array.map() 在 buildUnionDef (chrome-extension://fkkiamalmpiidkljmicmjfbieiclmeij/dist/chromeiql.js:72566:47) 在 buildType (chrome-extension://fkkiamalmpiidkljmicmjfbieiclmeij/dist/chromeiql.js:725

所以我认为我的类型定义有问题,但我不明白为什么。有什么想法吗?

tl;dr:我想要一个 GraphQL 字段,它可以接受一个标量值一个带有这个标量类型作为字段的 InputObject。甚至有可能吗?

提前致谢!

解决方法

GraphQL 当前不支持 input 中的多态输入类型或联合。 https://github.com/graphql/graphql-spec/issues/488

一种解决方案可以是 all_regions 到输入架构的一部分,但不是强制性的

input Regions{
   eur: Boolean
   usa: Boolean
   jpa: Boolean
   all_regions: Boolean
}

    {
      games(has_been_released: { all_regions: true}) {
        data {
          name
          release_date
        }
      }
    }