【问题标题】:Dynamically creating Apollo GraphQL mutation call in Angular在 Angular 中动态创建 Apollo GraphQL 突变调用
【发布时间】:2020-07-15 23:27:17
【问题描述】:

我在我的 Angular 应用程序中有一个有效的突变调用,用于使用 Apollo GraphQL 对一个对象的某些字段进行突变。变异调用的一部分包括一些返回数据,Apollo 将与已经在其缓存中的某个对象相关联,并使用返回的新值对其进行更新。

我只想返回实际发生变异的字段,以避免通过网络发送大数据包。

我已经成功地动态生成了一个仅包含被变异字段的变异文档,并且我将其传递给apollo.mutate({mutation: newMutation, ...}),它返回一个可观察的对象。只有订阅了该 observable 后,才会触发突变。我已验证使用该订阅的组件在调用新突变之前正在取消订阅并被销毁。

问题在于 Apollo 正在缓存变异文档并为所有调用发送第一个变异(只有第一次变异的字段)。我已通过检查我的网络浏览器的网络标签验证了这一点。

我尝试让 Apollo 通过附加日期时间来使用唯一的突变名称来停止缓存它。我已经检查过突变的变量是唯一的。我试过使用片段,但片段也需要动态生成,这是同样的问题。

有人知道我做错了什么吗?

【问题讨论】:

  • 准备minimal reproducible example - 发送/接收key/val数组(写入缓存)?
  • Apollo Client 本身不会这样做。 Apollo 做的唯一缓存是查询结果——它不缓存传递给它的 DocumentNode。您的代码中很可能还有其他东西导致了这种行为——如果您使用的不是 HttpLink 或您在 Apollo 的 API 上编写的一些自定义包装器,那么可能是一个链接?

标签: angular graphql apollo


【解决方案1】:

好的,我想通了。 Apollo 客户端正在向其 ROOT_MUTATION 添加变异文档。我发现使用 Apollo Client 的 writeData/writeQuery 函数只能让您添加/修改 ROOT_QUERY。

最初我试图将字段动态添加到我的GraphQL AST。代码看起来像这样:

import gql from 'graphql-tag';
...
const myMutation = gql`
  mutation myMutation($id: ID!, ...) {
    mutateFields(id: $id, ...) {
      id  # You need to return at least one field or it will complain
      # Add mutated fields to return here
    }
  }
`;

# dynamically call the following lines based on fields to be added
myMutation.definitions[0].selectionSet.selections[0].selectionSet.selections = [
  {...}  # Added my own fields and their subfields here
];

问题在于它第一次工作,所以我知道我正确地修改了 GraphQL AST,但随后的调用(返回新字段)被正确创建,但 Apollo 发送了第一个同名突变(我检查了浏览器的网络选项卡以进行验证)。

解决方案:

不要修改 GraphQL AST,而是将其修改为字符串文字,类似于 Alireza Hariri 在这篇文章中的评论:GraphQL dynamic query building

示例代码:

const mainMutation = `
   mutation myMutation($id: ID!, ...) {
    mutateFields(id: $id, ...) {
      id  # You need to return at least one field or it will complain
      # REPLACE_THIS_WITH_FIELDS
    }
  }
`;

const mutationWithFields = mainMutation.replace(
  `# REPLACE_THIS_WITH_FIELDS`,
  "myField { mySubfield1 mySubfield2 }"
);

const finalMutation = gql`${mutationWithFields}`;
this.apollo.mutate({
  mutation: finalMutation,
  variables: {
    id: myId,
    ...
  }
});

【讨论】:

    猜你喜欢
    • 2019-06-11
    • 2020-09-11
    • 2020-04-24
    • 2019-07-26
    • 2019-04-14
    • 2019-11-27
    • 2021-07-05
    • 2022-10-23
    • 2018-12-20
    相关资源
    最近更新 更多