在 GraphQL 中查询未知数据结构
Query unknown data structure in GraphQL
我刚开始使用 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。作为额外信息,我总是想查询整个内容部分,而不是单个元素或字段,而是所有内容。
当您要返回一个对象类型数组,但每个单独的项目可能是任意数量的不同对象类型之一时,您可以使用接口或联合。我们可以在这里使用接口,因为所有实现类型共享一个字段 (type
)。
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:[=18 仅查询特定于每个实现类型的字段=]
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。
我刚开始使用 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。作为额外信息,我总是想查询整个内容部分,而不是单个元素或字段,而是所有内容。
当您要返回一个对象类型数组,但每个单独的项目可能是任意数量的不同对象类型之一时,您可以使用接口或联合。我们可以在这里使用接口,因为所有实现类型共享一个字段 (type
)。
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:[=18 仅查询特定于每个实现类型的字段=]
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。