[英]How should I query and match data from the same response in GraphQL with Apollo Client and Link Rest?
I have the following query: 我有以下查询:
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
}
}
}
In blocks.posts.author
there's only an AuthorId
. 在
blocks.posts.author
,只有一个AuthorId
。 The authors object is containing all the available authors. 作者对象包含所有可用的作者。
I'd like to replace/match the AuthorId
with it's corresponding object. 我想用它的相应对象替换/匹配
AuthorId
。 Is it possible to do this within one query? 是否可以在一个查询中执行此操作?
I also wouldn't mind to have a separate query for Author only (fetch will be cached, no new request would be made), but I still don't know how would I match it through 2 queries. 我也不介意只为Author提供一个单独的查询(fetch将被缓存,不会有新请求),但我仍然不知道如何通过2个查询匹配它。
Example API response 示例API响应
{
blocks: [
{
posts: [
{
id: 1,
title: 'My post',
author: 12,
}
]
}
],
authors: [
{
id: 12,
name: 'John Doe'
}
]
}
What I want with 1 query that author
inside a post
becomes the full author object. 我想要1个查询,
post
内的author
成为完整的作者对象。
Great question. 好问题。 With GraphQL, you have the power to expand any field and select the exact subfields you want from it, so if you were using GraphQL on your backend as well this would be a non-issue.
使用GraphQL,您可以扩展任何字段并从中选择您想要的确切子字段,因此如果您在后端使用GraphQL,那么这将是一个非问题。 There are some workarounds you can do here:
您可以在此处执行一些变通办法:
If all of the Author objects are in your Apollo cache and you have access to each Author's id, you could use ApolloClient.readFragment to access other properties, like this: 如果所有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
}
`,
});
Although it's worth noting that with your original query in the question, if you have all of the Author objects as a property of the query, you could just use Javascript operations to go from Author id to object. 虽然值得注意的是,对于问题中的原始查询,如果您将所有Author对象作为查询的属性,则可以使用Javascript操作从Author id转到object。
const authorId = ...; // the id of the author
data.page.authors.find(author => author.id === authorId);
The following should work. 以下应该有效。
First, capture the author id as a variable using the @export directive. 首先,使用@export指令将作者id捕获为变量。 Then add a new field with some name other than
author
and decorate it with the @rest , using the exported variable inside the path. 然后使用除了
author
之外的某个名称添加一个新字段,并使用@rest中的导出变量使用@rest进行装饰。
So the query would look something like this: 所以查询看起来像这样:
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
}
}
}
You can use the fieldNameNormalizer
option to rename the author
property in the response to a field with a different name (for example, authorId
). 您可以使用
fieldNameNormalizer
选项将响应中的author
属性重命名为具有不同名称的字段(例如, authorId
)。 Ideally, that should still work with the above so you can avoid having a weird field name like authorFull
but apollo-link-rest is a bit wonky so no promises. 理想情况下,这应该仍然适用于上面所以你可以避免像
authorFull
一样奇怪的字段名称,但apollo-link-rest有点不稳定,所以没有承诺。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.