首页 文章

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

提问于
浏览
0

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

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

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

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

  • 在客户端手动过滤

  • 将中间件添加到阿波罗

  • 将__typename字段添加到我的所有模式中......

但是它们似乎都不符合“简单性”,阿波罗想要带来查询 . 我希望提供一个更简单,更合理的解决方案,但到目前为止,找不到任何解决方案 .

1 回答

  • 1

    即使使用 apollo-client 而不是 apollo-boost ,除非有令人信服的理由,否则不应将 addTypename 设置为false . InMemoryCache 字段由 InMemoryCache 用于规范化查询结果,因此省略它可能会导致缓存周围出现意外行为 .

    不幸的是,这个问题没有"silver bullet" . 请求查询然后将该查询的数据用作某些其他查询的变量可能被解释为滥用API . 查询返回的 Type 和用作参数的 Input Type 是完全不同的东西,即使它们共享一个或多个字段作为Javascript对象 . 就像你可以期望它们可以在客户端互换使用 .

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

    如果你大概已经将初始查询数据转换为组件状态,然后在你的变异中使用它 . 在这种情况下, __typename 或任何其他不可编辑的字段可能不应该首先作为组件状态的一部分包含在内 .

    在一天结束时,做这些操作有望成为例外,而不是规则 . 我会创建一些辅助函数来“消毒”你的输入并继续前进 .

    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
        }
    }
    

相关问题