【问题标题】:GraphQL Tag dynamic table name in query (apollo)查询中的 GraphQL Tag 动态表名(apollo)
【发布时间】:2022-02-06 18:31:25
【问题描述】:

在我的应用中,每个客户都有自己的数据表。根据选择的客户,我想为 Graphql 查询动态构建表名。

例如:

// Query for customer 1
gql`
  query overviewQuery {
    customer_1 {
      aggregate {
        count
      }
  }
}
`
// Query for customer 2
gql`
  query overviewQuery {
    customer_2 {
      aggregate {
        count
      }
  }
}
`

我在我的 vuex 商店中有客户 ID,并且想在查询中插入一个变量,就像下面的伪代码一样,但它不起作用。

const tblUserAggregateName = `customer_${this.$store.state.customer.customerId`

gql`
  query overviewQuery {
    ${this.tblUserAggregateName} {
      aggregate {
        count
      }
  }
`

是否可以选择如何执行此操作或如何解决此问题?

不能硬编码所有不同的客户查询并在运行时选择它们。

谢谢!

【问题讨论】:

    标签: graphql apollo hasura vue-apollo graphql-tag


    【解决方案1】:

    您可以提供变量,但不应使用它们来动态推断架构对象名称。这违反了 GraphQL 的核心概念。试试这个:

    gql`
      query overviewQuery ($customerId: ID!) {
        customerData (id: $customerId) {
          tableName
          aggregate {
            count
          }
        }
      }`
    

    Apollo 在此处提供了有关如何将变量提供给查询的出色文档:https://www.apollographql.com/docs/react/data/queries/

    然后后端可以使用 customerId 来确定要查询的表。发出请求的客户端不需要知道(也不应该知道)该数据在哪里或如何存储。如果客户端必须知道表名,可以添加字段(如示例所示)

    【讨论】:

    • 感谢您的解释。因此,当使用 graphql 时,我必须自动使用多个租户共享同一个表/数据库并使用 columnId 标识的数据库设计?
    • GraphQL 只是另一种 API 方法(类似于 REST 或 gRPC)。它只是将客户端连接到后端的粘合剂,提供了一些优于 REST/gRPC 的优势(此处比较:medium.com/devops-dudes/graphql-vs-rest-vs-grpc-411a0a60d18d)。您仍然可以将租户数据单独存储在后端,并使用 id 生成表名并返回适当的数据。
    【解决方案2】:

    在提到的答案中,动态更改 GraphQL 查询的表名是违反最佳实践的。

    由于更改所有客户端的完整数据库结构(他们每个人都有一个单独的数据库和自己的 PostgreSQL 模式名称)不是一个选项,我找到了一个看起来有点 hacky 并且绝对不是最佳实践的解决方案,但我认为我分享给有同样问题的其他人可能会很有趣。

    这个方法很简单:我将查询写成一个简单的字符串,我可以在其中使用变量,然后用graphql-tag将它们转换为gql AST对象

    const query = () => {
      const queryString = `
        {
          ${customerId}_table_name {
            aggregate {
               count
            }
          }
      }`
    
      return gql`${queryString}`
    }
    
    

    有效,但我有更好的解决方案,我很高兴学习!

    【讨论】:

      猜你喜欢
      • 2019-01-07
      • 2019-06-09
      • 2018-06-13
      • 2017-12-02
      • 2018-10-19
      • 2022-10-23
      • 2020-10-01
      • 2018-03-02
      • 2021-07-04
      相关资源
      最近更新 更多