Executing multiple queries concurrently

Note: Module "Multiple Query Execution" must be enabled to use this functionality (it is disabled by default). Check in guide Browsing, enabling and disabling modules on how to enable it.

Multiple queries can be combined together, and executed as a single operation, reusing their state and their data. In this case, if a first query fetches some data, and a second query also accesses the same data, this data is retrieved only once from the database, not twice.

The multiple queries are executed in the same requested order.

Note: This is different from query batching, in which the GraphQL server also executes multiple queries in a single request, but those queries are merely executed one after the other, independently from each other.

This feature improves performance. Instead of executing queries independenty in different requests (so that we first execute an operation against the GraphQL server, then wait for its response, and then use that result to perform another operation), we can execute them together, thus avoiding the latency from the several request(s).

Sharing data across queries via @export permalink

Queries can access the data from a previous query through the @export directive, which injects the result of a field from a query, as an input into a subsequent query.

Directive @export has a couple of requirements for the target variable (i.e. where the value will be exported to):

  1. The variable must have a name starting with "_" (eg: $_search, not $search)
  2. The variable must be declared in the operation name, and always receive a default value (eg: query SearchPosts($_search: String = ""))

How to use multiple query execution permalink

Let's suppose we want to search all posts which mention the name of the logged-in user. Normally, we would need two queries to accomplish this:

We first retrieve the user's name:

query GetLoggedInUserName {
me {
name
}
}

...and then, having executed the first query, we can pass the retrieved user's name as variable $_search to perform the search in a second query:

query GetPostsContainingString($_search: String = "") {
posts(searchfor: $_search) {
id
title
}
}

The @export directive exports the value from a field, and inject this value into a second field through a dynamic variable (whose name is defined under argument as), and we can execute both queries together:

query GetLoggedInUserName {
me {
name @export(as: "_search")
}
}

query GetPostsContainingString($_search: String = "") {
posts(searchfor: $_search) {
id
title
}
}

Demonstration permalink

In the image below, there are 2 queries:

  1. GetAuthorName
  2. GetPostsWithString

These are executed in 3 separate stages:

  1. First, they are executed independently
  2. Then, they are executed together
  3. Finally, they are executed together while sharing data, where the ouput from GetAuthorName is injected as input into GetPostsWithString

Executing queries independently, and then all together as a single operation
Executing queries independently, and then all together as a single operation

Execution in GraphiQL permalink

The GraphiQL client currently does not allow to execute multiple operations.

To bypass this issue, whenever the executed operation has name __ALL, the GraphQL server will execute all queries. Hence, within the GraphiQL editor, append the following code:

query __ALL { id }

Then, you can execute operation __ALL from the dropdown when clicking on the "Run" button:

Executing multiple queries in GraphiQL
Executing multiple queries in GraphiQL

Exporting data permalink

@export handles these 4 cases:

  1. Exporting a single value from a single field
  2. Exporting a list of values from a single field
  3. Exporting a dictionary of values, containing several fields from the same object
  4. Exporting a list of a dictionary of values, with each dictionary containing several fields from the same object

1. Exporting a single value from a single field permalink

@export handles exporting a single value from a single field.

For instance, the user's name field, with type String, is exported:

query GetLoggedInUserName {
me {
name @export(as: "_search")
}
}

query GetPostsContainingString($_search: String = "") {
posts(searchfor: $_search) {
id
title
}
}

2. Exporting a list of values from a single field permalink

@export handles exporting lists.

For instance, list of names from the logged-in user's friends, with type [String], are exported (hence the type of the $search variable went from String to [String]):

query GetLoggedInUserFriendNames {
me {
friends {
name @export(as: "_search")
}
}
}

query GetPostsContainingLoggedInUserFriendNames($_search: [String] = []) {
posts(searchAny: $_search) {
id
title
}
}

3. Exporting a dictionary of values, containing several fields from the same object permalink

@export handles exporting several properties from a same object, creating a dictionary of values containing the exported properties.

For instance, both the name and surname fields from the user are exported, creating an object which contains these 2 properties:

query GetLoggedInUserNameAndSurname {
me {
name @export(as: "_search")
surname @export(as: "_search")
}
}

query GetPostsContainingLoggedInUserNameAndSurname($_search: JSONObject = {}) {
posts(searchByAnyProperty: $_search) {
id
title
}
}

4. Exporting a list of a dictionary of values, with each dictionary containing several fields from the same object permalink

@export handles exporting several properties from a list of objects, creating a list of dictionaries of values containing the exported properties.

For instance, fields name and surname from the list of the logged-in user's friends are exported:

query GetLoggedInUserFriendNamesAndSurnames {
me {
friends {
name @export(as: "_search")
surname @export(as: "_search")
}
}
}

query GetPostsContainingLoggedInUserFriendNamesAndSurnames($_search: [JSONObject] = []) {
posts(searchAnyByAnyProperty: $_search) {
id
title
}
}

GraphQL spec permalink

This functionality is currently not part of the GraphQL spec, but it has been requested:

Share on 🐦 Twitter | πŸ‘ŽπŸΎ Facebook