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

时间:2019-07-23 13:06:13

标签: graphql apollo-client apollo-link-rest

我有以下查询:

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个查询来匹配它。

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有点古怪,因此没有任何保证。