GraphQL Tag dynamic table name in query (apollo)

1k Views Asked by At

In my app every customer has a own table for its data. Depending on which customer was selected I want to dynamically build the tablename for the Graphql query.

For example:

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

I have the customer id in my vuex store and want to insert a variable into the query like in the following pseudocode which is not working.

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

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

Is there an option how to do this or how can this problem be solved?

It is not an option to hardcode all different customer queries and selected them on runtime.

Thanks!

2

There are 2 best solutions below

0
Thomas K. On BEST ANSWER

In the answers it was mentioned, that it is against best practice to dynamically change the table name of GraphQL queries.

As changing the complete database structure for all clients (they each have a separate Database with a own PostgreSQL schema name) is not an option, I found a solution the looks a little bit hacky and definitely not best practice but I thought I might be interesting to share for others with the same problem.

The approach is pretty easy: I write the query as a simple string where I could use variables and convert them later to the gql AST Object with graphql-tag

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

  return gql`${queryString}`
}

Works, but I you have a better solution, I am happy to learn!

2
Bemis On

You can supply variables, but they should not be used to dynamically infer schema object names. This violates core concepts of GraphQL. Try this instead:

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

Apollo provides great documentation on how to supply variables into a query here: https://www.apollographql.com/docs/react/data/queries/

The backend can then use the customerId to determine what table to query. The client making requests does not need to know (nor should it) where that data is or how it's stored. If the client must know the table name, you can add a field (as shown in the example)