我有以下查询:
const getPage = gql`
query Page($path: String!) {
page(path: $path) @rest(type: "Page", path: "{args.path}") {
blocks @type(name: Block) {
name
posts @type(name: Post) {
body
author
}
}
authors @type(name: Author) {
name
}
}
}
在blocks.posts.author
中只有一个AuthorId
。 authors对象包含所有可用的作者。
我想用其对应的对象替换/匹配AuthorId
。是否可以在一个查询中执行此操作?
我也不介意仅对Author进行单独的查询(提取将被缓存,不会发出新请求),但是我仍然不知道如何通过2个查询来匹配它。
答案 0 :(得分:1)
很好的问题。使用GraphQL,您可以扩展任何字段并从中选择所需的确切子字段,因此,如果您也在后端使用GraphQL,那将是不成问题的。您可以在此处执行一些解决方法:
如果所有Author对象都在您的Apollo缓存中,并且您有权访问每个Author的ID,则可以使用ApolloClient.readFragment访问其他属性,例如:
const authorId = ...; // the id of the author
const authorInfo = client.readFragment({
id: authorId,
fragment: gql`
fragment AuthorInfo on Author {
id
name
# anything else you want here
}
`,
});
尽管值得注意的是,对于问题中的原始查询,如果您具有所有Author对象作为查询的属性,则可以使用Javascript操作将Author ID转换为Object。
const authorId = ...; // the id of the author
data.page.authors.find(author => author.id === authorId);
答案 1 :(得分:0)
以下应能工作。
首先,使用@export指令将作者ID捕获为变量。然后使用路径内的导出变量,添加一个名称为author
以外的名称的新字段,并用@rest装饰它。
因此查询看起来像这样:
query Page($path: String!) {
page(path: $path) @rest(type: "Page", path: "{args.path}") {
blocks @type(name: Block) {
name
posts @type(name: Post) {
body
author @export(as: "authorId")
authorFull @rest(
path: '/authors/{exportVariables.authorId}'
type: 'Author'
) {
name
}
}
}
authors @type(name: Author) {
name
}
}
}
您可以使用fieldNameNormalizer
option将响应中的author
属性重命名为具有不同名称的字段(例如authorId
)。理想情况下,上面的方法仍然可以使用,因此您可以避免使用诸如authorFull
之类的怪异字段名,但是apollo-link-rest有点古怪,因此没有任何保证。