reactjs - Apollo boost - 查询中的 __typename 防止新突变

标签 reactjs graphql apollo apollo-client apollo-boost

我的 meteor/react/apollo(带 boost)项目有问题。当我从服务器查询数据时,它会将 __typename 添加到我查询中的每个对象和子对象,但在我的情况下,它会产生一个主要问题,因为我通常会重用这些数据将它们发送到其他突变。现在另一个突变告诉我有一个错误,因为 __typename 字段没有在我的 graphql 模式中定义。

我试图通过将 addTypename: false 字段添加到我的 apollo 客户端来修复,但它没有改变任何东西(注意我正在使用 apollo boost,这可能是它不工作的原因):

const client = new ApolloClient({
    uri: Meteor.absoluteUrl('graphql'),
    addTypename: false,
    request: operation =>
        operation.setContext(() => ({
            headers: {
                authorization: Accounts._storedLoginToken()
            }
        }))
})

此外,即使它有效,它似乎也不是很优化。在我看来,在查询结果中添加一个字段是非常有问题的,我很惊讶没有在网上找到任何明确的解决方案。一些建议的解决方案,其中:

  • 在客户端手动过滤
  • 为apollo添加中间件
  • 将 __typename 字段添加到我的所有模式中...

但它们似乎都不符合 apollo 假设带来的查询“simplcity”。我希望有一个更简单、更合乎逻辑的解决方案,但到目前为止,还没有找到。

最佳答案

即使使用 apollo-client 而不是 apollo-boost,你也不应该将 addTypename 设置为 false,除非你有令人信服的理由这样做。 __typename 字段由 InMemoryCache 使用以规范化您的查询结果,因此省略它可能会导致围绕缓存的意外行为。

不幸的是,这个问题没有“ Elixir ”。请求查询,然后将该查询的数据用作其他查询的变量可能会被视为滥用 API。查询返回的 Type 和用作参数的 Input Type 是完全不同的东西,即使作为 Javascript 对象它们共享一个或多个字段。就像您不能在模式中互换使用类型和输入类型一样,也不应期望它们可以在客户端互换使用。

这也意味着,如果您发现自己处于这种情况,您可能需要重新审视您的架构设计。毕竟,如果数据已经存在于服务器上,为其传递一个 id 并在服务器端检索它就足够了,而不必传递整个对象。

如果您正在使用一些查询来填充一个或多个输入,然后在突变中使用这些输入的值,那么您可能已经将初始查询数据转换为组件状态,然后在您的突变中使用它。在这种情况下,__typename 或任何其他不可编辑的字段可能首先不应作为组件状态的一部分包含在内。

归根结底,进行此类操作有望成为异常(exception),而不是常规。我会创建某种辅助函数来“清理”您的输入并继续。

function stripTypenames (value) {
    if (Array.isArray(value)) {
        return value.map(stripTypenames)
    } else if (value !== null && typeof(value) === "object") {
      const newObject = {}
      for (const property in value) {
          if (property !== '__typename') {
            newObject[property] = stripTypenames(value[property])
          }
      }
      return newObject
    } else {
      return value
    }
}

关于reactjs - Apollo boost - 查询中的 __typename 防止新突变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52873741/

相关文章:

javascript - Koa 将数据从服务器传递到客户端

javascript - 移动菜单切换按钮将页面移至 React 顶部

javascript - graphql 突变中无法识别的参数

ios - 无法连接到 Hasura PostGreSQL docker 容器的网络套接字

graphql - 为 GraphQL 中的字段分配多种类型

vue.js - 如何为 Vue Apollo 导入 Apollo Client 3?

javascript - React.js import 语句找不到模块

javascript - 如何在 ReactJs 中链接下拉菜单和文本区域

ios - 同一 View Controller 中的 AWS AppSync 多个订阅不起作用 - iOS Swift

node.js - express-session不设置cookie?