我刚刚开始使用GraphQL,目前正在使用webonyx / graphql-php设置服务器。由于GraphQL查询已经必须包含结果数据结构,因此我不太确定如何获取动态数据。假设我查询包含不同元素类型的内容,并且最终结构应如下所示:
{
"data": {
"dataset": {
"uuid": "abc...",
"insertDate": "2018-05-04T12:12:12Z",
// other metadata
"content": [
{
"type": "headline",
"text": "I am a headline"
},
{
"type": "image",
"src": "http://...",
"alt": "I am an image"
},
{
"type": "review",
"rating": 3,
"comment": "I am a review"
},
{
"type": "headline",
"text": "I am another headline"
}
// other content elements
]
}
}
}
如何为该示例编写查询?
{
dataset {
uuid
insertDate
content {
????
}
}
}
内容部分的类型定义如何?有一组定义的元素类型(标题,图像,评论等等),但是元素的顺序和数量未知,并且它们只有一个字段,类型相同。在前端编写查询时,我对内容结构一无所知。内容部分的graphql-php类型定义是什么样的?我在网上找不到任何类似的示例,因此我不确定是否有可能在此用例中使用GraphQL。作为额外的信息,我始终希望查询整个内容部分,而不是单个元素或字段,而总是查询所有内容。
答案 0 :(得分:0)
当您返回对象类型的数组,但是每个单独的项目可以是任意数量的不同对象类型之一时,可以使用接口或联合。因为所有实现类型都共享一个字段(type
),所以我们可以在这里使用Interface。
use GraphQL\Type\Definition\InterfaceType;
use GraphQL\Type\Definition\Type;
$content = new InterfaceType([
'name' => 'Content',
'description' => 'Available content',
'fields' => [
'type' => [
'type' => Type::nonNull(Type::string()),
'description' => 'The type of content',
]
],
'resolveType' => function ($value) {
if ($value->type === 'headline') {
return MyTypes::headline();
} elseif ($value->type === 'image') {
return MyTypes::image();
} # and so on
}
]);
实现接口的类型需要在其定义中明确地这样做:
$headline = new ObjectType([
# other properties
'interfaces' => [
$content
]
]);
现在,如果将content
字段的类型更改为content
的列表,则可以使用inline fragments仅查询特定于每种实现类型的字段:
query GetDataset {
dataset {
uuid
insertDate
content {
type # this field is shared, so it doesn't need an inline fragment
... on Headline {
text
}
... on Image {
src
alt
}
# and so on
}
}
}
有关更多详细信息,请参见the docs。