简体   繁体   English

我应该如何使用Apollo Client和Link Rest查询和匹配GraphQL中相同响应的数据?

[英]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.

相关问题 Graphql 响应不是来自 Apollo 客户端查询 - Graphql response not coming from Apollo client query 在 Javascript 中使用 GraphQL + Apollo 客户端查询具有部分字符串匹配的数据 - Query data with partial string match using GraphQL + Apollo client in Javascript 两种类型之间的链接数据 GraphQl (apollo,express) 如何按标题匹配数据? - Link data between two types GraphQl (apollo,express) How do I match the data by the title? Apollo 客户端 Angular:如何将从查询中获得的数据作为参数传递给 graphql 中的另一个查询? - Apollo Client Angular: how to pass the data obtained from a query as an argument in another query in graphql? 将Redux客户端从REST转换为GraphQL Apollo吗? - Converting redux client from REST to GraphQL Apollo? 如何将数据从React组件传递到Apollo graphql查询? - How to pass data from react component to Apollo graphql query? 无法将GraphQL查询从Apollo客户端发送到Rails GraphQL后端 - Cannot send GraphQL query from Apollo Client to Rails GraphQL backend 无法转换/规范化/修改 GraphQL 查询的响应 - Apollo Client - Can't transform/normalize/modify response of GraphQL query - Apollo Client GraphQL/Apollo 客户端:如果查询是先前查询的子集,则从缓存中获取数据 - GraphQL/Apollo Client: get data from cache if a query is a subset of a previous query 调用Apollo Client的GraphQL查询 - invoking Query of GraphQL of Apollo Client
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM