GraphQL query syntax for Cube.js

Migrating an issue from GitHub that @igorlukanin started.

I’d like to propose a new GraphQL query syntax for Cube.js as an alternative to the current JSON-based Cube.js query format. This new GraphQL query syntax might be more concise, expressive, and developer-friendly as GraphQL has already gained a lot of popularity.

It would certainly be a massive effort including these steps:

  • a documented GraphQL-based query syntax is added to Cube.js
  • a GraphQL server is included into Cube.js and ran alongside the current REST API
  • based on the data schema provided, GraphQL type definitions are generated automatically

However, as Cube.js query syntax supports numerous features, such as Data Blending, is maybe tricky to provide an alternative query syntax that covers all existing features and use cases.

Here’s a few examples of what this new GraphQL query syntax might look like.

1a. A simple query using the current Cube.js query syntax:

{
   measures: [ 'Repos.count' ],
   dimensions: [ 'Repos.language' ],
}

1b. A simple query using the proposed Cube.js GraphQL query syntax

{
   Repos {
      count
      language
   }
}

2a. A complex query using the current Cube.js query syntax:

const MostUsedKnownLanguage = {
   measures: [ 'Repos.count' ],
   dimensions: [ 'Repos.language' ],
   filters: [ {
    dimension: 'Repos.language',
    operator: 'notEquals',
    values: [ 'Unknown' ],
  }  ],
  order: {
    'Repos.count': 'desc',
  },
  limit: 1,
}

2b. A complex query using the proposed Cube.js GraphQL query syntax

query MostUsedKnownLanguage(limit: 1) {
  Repos {
    count(orderBy: DESC)
    language(filter: { operator: NOT_EQUALS, values: [ 'Unknown' ] })
  }
}

Follow-up exchanges between Matt and @igorlukanin:

Matt
I don’t think the proposed syntax really makes sense.

This query:

{
  Repos {
    count
    language
  }
}

implies that the response json would be:

{
    "repos": {
        "count": {...}
        "language": {...}
    }
}

I assume this is not what is actually intended?

Igor
You’re right, the constraint that GraphQL query shape matches the response shape is certainly violated here. Is it really an issue? I assume that one should work with Cube.js ResultSet object and its methods anyway rather than use the response data directly.

Matt
I suppose this constraint is not really an issue? I feel like it might be difficult to benefit from GraphQL though? The main benefit I can see would be utilising the schema and existing tooling for this. Of particular benefit are things like type generation and auto-documentation which cannot be done easily with REST.

If there is no query response schema, then what is the benefit? The query syntax seems like it would be an improvement in that it can be linted and auto-completed with existing tooling but not otherwise. I would say that using GraphQL syntax without describing a graph is not intuitive and probably a downgrade from the current query syntax, particularly for people who already use GraphQL regularly.

Think Bitquery did something similar. They build GraphQL on top of their activecube and Clickhouse. So I think their syntax can be a good inspiration:

Result: GraphQL IDE
Video: [Community Meetup] BitQuery Explores GraphQL for Analytics on ClickHouse - YouTube

So I do not really think it would be downgrade to current query syntax.

2 Likes

thanks for the awesome information.

1 Like