Documentation
GraphQL API

GraphQL API

GraphQL API enables Cube to deliver data over the HTTP protocol to GraphQL (opens in a new tab)-enabled data applications, e.g., most commonly, front-end applications.

Often, the GraphQL API is used to enable the embedded analytics (opens in a new tab) use case.

Under the hood, the GraphQL API is exposed via the /graphql endpoint of the REST API.

See GraphQL API reference for the list of supported requests and parameters.

Compared to the REST API, GraphQL API currently has the following limitations:

Configuration

GraphQL API is enabled by default and secured using API scopes and CORS. To disallow access to GraphQL API, disable the graphql scope, e.g., by setting the CUBEJS_DEFAULT_API_SCOPES environment variable to meta,data.

Getting started

First, ensure you're running Cube v0.28.58 or later. Then start the project locally in development mode, and navigate to http://localhost:4000/ in your browser. After generating data models and running query you should see the GraphiQL interface if you click 'GraphiQL' button. If you click the 'Docs' button in the top-right, you can explore the introspected schema.

As an example, let's use the orders cube from the example eCommerce database:

YAML
JavaScript
cubes:
  - name: orders
    sql_table: orders
 
    measures:
      - name: count
        type: count
 
    dimensions:
      - name: status
        sql: status
        type: string
 
      - name: created_at
        sql: created_at
        type: time

A GraphQL query to return the number of orders by status would look something like this:

{
  cube {
    orders {
      count
      status
      created_at {
        day
      }
    }
  }
}

The equivalent query to the REST API endpoint would look like this:

{
  "measures": ["orders.count"],
  "dimensions": ["orders.status"],
  "timeDimensions": [
    {
      "dimension": "orders.created_at",
      "granularity": "day"
    }
  ]
}

Modifying time dimension granularity

The granularity for a time dimension can easily be changed by specifying it in the query:

{
  cube {
    orders {
      created_at {
        month
      }
    }
  }
}

Any supported granularity can be used. If you prefer to not specify a granularity, then use value:

{
  cube {
    orders {
      created_at {
        value
      }
    }
  }
}

Specifying filters and ranges

Filters can be set on the load query or on a specific cube. Specifying the filter on the load query applies it to all cubes in the query. Filters can be added to the query as follows:

query {
  cube(limit: 100, offset: 50, timezone: "America/Los_Angeles") {
    orders(
      orderBy: { created_at: asc, count: desc }
      where: { status: { equals: "completed" } }
    ) {
      count
      status
      created_at
    }
  }
}

Some other differences between the JSON query filters and the GraphQL filters to note:

  • number values are used for number types instead of strings
  • The notSet filter is replaced by { set: false }
  • New in and notIn filters to check for multiple values
  • AND and OR fields for boolean operators

The GraphQL API supports @skip and @include directives too:

query GetOrders($byStatus: Boolean) {
  cube(limit: 100, offset: 50, timezone: "America/Los_Angeles") {
    orders(
      orderBy: { created_at: asc, count: desc }
      where: { status: { equals: "completed" } }
    ) {
      count
      status @include(if: $byStatus)
      created_at
    }
  }
}

Querying multiple cubes

Using the same orders cube as before, let's try and get the numbers of products for each order status too. We can do this by adding the products cube to our query as follows:

{
  cube {
    orders {
      status
      count
      created_at {
        month
      }
    }
    products {
      count
    }
  }
}