Skip to content
Last updated: 2026-04-06
Reference

GraphQL Request Batching

Execute multiple GraphQL operations in a single HTTP request to the GraphQL API.

Execution Model

The API executes batched queries sequentially and returns combined results. This reduces network round trips but does not provide parallel execution.

When to Use Batching

Batching is beneficial when you need to:

  • Fetch data from multiple unrelated tables simultaneously
  • Initialize application state requiring several independent queries
  • Reduce network overhead in high-latency environments (mobile, edge networks)

Not recommended for:

  • Operations that depend on each other (use sequential requests instead)
  • Real-time updates (use subscriptions)
  • Large bulk mutations (use insert_many mutations with arrays)

Batch Request Format

The API accepts an array of GraphQL request objects:

JSON
[
  {
    "query": "query GetControllers { dataControllers { id title } }"
  },
  {
    "query": "query GetSubjects($limit: Int!) { dataSubjects(limit: $limit) { id did } }",
    "variables": { "limit": 10 }
  }
]

Sequential Execution

The API processes batched queries in order. If query 2 depends on results from query 1, use separate requests instead.

Implementation Examples

TypeScript with graphql-request

TypeScript
import { GraphQLClient, gql } from 'graphql-request';

const client = new GraphQLClient('https://api.dxtra.ai/v1/graphql', {
  headers: {
    'Authorization': `Bearer ${jwt}`,
    'X-Hasura-Role': 'user'
  }
});

// Batch multiple queries
const results = await client.batchRequests([
  {
    document: gql`
      query GetControllers {
        dataControllers {
          id
          title
          createdAt
        }
      }
    `
  },
  {
    document: gql`
      query GetActiveSubjects($limit: Int!) {
        dataSubjects(
          limit: $limit
        ) {
          id
          did
        }
      }
    `,
    variables: { limit: 50 }
  }
]);

// Access results by index
const controllers = results[0].data.dataControllers;
const subjects = results[1].data.dataSubjects;
TypeScript
import { batchRequests, gql } from 'graphql-request';

const results = await batchRequests('https://api.dxtra.ai/v1/graphql', [
  {
    document: gql`query GetControllers { dataControllers { id title } }`
  },
  {
    document: gql`query GetSubjects { dataSubjects(limit: 10) { id did } }`
  }
]);

Python with gql

Python
from gql import Client, gql
from gql.transport.aiohttp import AIOHTTPTransport
import asyncio

# Create transport with authentication
transport = AIOHTTPTransport(
    url='https://api.dxtra.ai/v1/graphql',
    headers={
        'Authorization': f'Bearer {jwt_token}',
        'X-Hasura-Role': 'user'
    }
)

client = Client(transport=transport, fetch_schema_from_transport=False)

# Define queries
query1 = gql("""
    query GetControllers {
        dataControllers {
            id
            title
            createdAt
        }
    }
""")

query2 = gql("""
    query GetRightsRequests($controllerId: uuid!) {
        dataSubjectsRightsRequests(
            where: {dataSubject: {dataControllerId: {_eq: $controllerId}}}
        ) {
            id
            requestType
            status
        }
    }
""")

async def fetch_data():
    # Execute queries concurrently (gql library doesn't support batch API)
    async with client as session:
        result1, result2 = await asyncio.gather(
            session.execute(query1),
            session.execute(query2, variable_values={'controllerId': controller_id})
        )

    return result1, result2

# Run async function
results = asyncio.run(fetch_data())

Python GraphQL Clients

The gql library does not provide a batch API. Use asyncio.gather() for concurrent execution of multiple queries.

Multiple Queries in a Single Document

The API also supports multiple root-level fields in a single GraphQL document:

GraphQL
query CombinedData {
  dataControllers {
    id
    title
  }
  dataSubjects(limit: 10) {
    id
    did
  }
}

This approach executes all fields and returns a single combined result object.

Practical Use Cases

Dashboard Data Loading

TypeScript
import { GraphQLClient, gql } from 'graphql-request';

async function loadDashboard(controllerID: string, jwt: string) {
  const client = new GraphQLClient('https://api.dxtra.ai/v1/graphql', {
    headers: {
      'Authorization': `Bearer ${jwt}`,
      'X-Hasura-Role': 'user'
    }
  });

  const [overview, activities, requests] = await client.batchRequests([
    {
      document: gql`
        query GetController($controllerID: uuid!) {
          dataControllers(where: {id: {_eq: $controllerID}}) {
            id
            title
            did
            createdAt
          }
        }
      `,
      variables: { controllerID }
    },
    {
      document: gql`
        query GetActivities($controllerID: uuid!, $limit: Int!) {
          dataProcessingActivities(
            where: { dataSubject: { dataControllerId: { _eq: $controllerID } } }
            limit: $limit
            order_by: { triggeredAt: desc }
          ) {
            id
            typeId
            triggeredAt
            type {
              label
            }
          }
        }
      `,
      variables: { controllerID, limit: 10 }
    },
    {
      document: gql`
        query GetRequests($controllerID: uuid!) {
          dataSubjectsRightsRequests(
            where: {
              dataSubject: { dataControllerId: { _eq: $controllerID } }
              status: { _eq: "pending" }
            }
          ) {
            id
            requestType
            createdAt
          }
        }
      `,
      variables: { controllerID }
    }
  ]);

  return {
    controller: overview.data.dataControllers,
    recentActivities: activities.data.dataProcessingActivities,
    pendingRequests: requests.data.dataSubjectsRightsRequests
  };
}

GraphQL Fragments

Use fragments for reusable field sets across batched queries:

GraphQL
fragment DataSubjectCore on dataSubjects {
  id
  did
  createdAt
}

query GetSubjectsWithActivities {
  dataSubjects {
    ...DataSubjectCore
    dataProcessingActivities(limit: 1, order_by: {triggeredAt: desc}) {
      typeId
      triggeredAt
    }
  }
}

Error Handling

The API returns errors for each failed query in the batch:

TypeScript
try {
  const results = await client.batchRequests([
    { document: query1 },
    { document: query2 }
  ]);

  // Check each result for errors
  results.forEach((result, index) => {
    if (result.errors) {
      console.error(`Query ${index} failed:`, result.errors);
    }
  });
} catch (error) {
  // Network or authentication error
  console.error('Batch request failed:', error);
}

Common Issues

Issue Solution
Query timeout Reduce query complexity or use pagination
Authentication failure Verify JWT token and X-Hasura-Role header
Variable type mismatch Ensure variables match schema types exactly
Network error Check endpoint URL and network connectivity

Alternative Approaches

GraphQL Aliases

Execute the same query multiple times with different arguments:

GraphQL
query MultipleControllers {
  controller1: dataControllers(where: {id: {_eq: "uuid-1"}}) {
    id
    title
  }
  controller2: dataControllers(where: {id: {_eq: "uuid-2"}}) {
    id
    title
  }
}

Next Steps