Debugging subgraph requests from the Apollo Router or @apollo/gateway
Log query plans and subgraph calls to help debug problematic queries
As your graph grows, you may need to debug a problematic query for one reason or another. The @apollo/gateway
Each client request goes through a process called
Output query plans with headers
With v0.16.0+
and @apollo/gateway
v2.5.4+
, you can pass the following headers to return the query plans in the GraphQL response extensions:
- Including the
Apollo-Query-Plan-Experimental
header returns the query plan in the response extensions - Additionally, including the
Apollo-Query-Plan-Experimental-Format
header with one of the supported options changes the output format:- A value of
prettified
returns a human-readable string of the query plan - A value of
internal
returns a JSON representation of the query plan
- A value of
Log Apollo Router subgraph calls
If, instead, you want to debug your subgraph HTTP requests in an Apollo Router instance, you can use
⚠️ CAUTION
While it's possible to log out the variables, Apollo strongly recommends not doing so to avoid leaking sensitive information into your logs.
fn subgraph_service(service, subgraph) {service.map_request(|request| {log_info(`Subgraph: ${subgraph} Query: ${request.subgraph.body.query}`);});}
The above uses an inline closure within the map_request
function of the subgraph_service
hook to log the subgraph-related information.
To enable query plans, you must run the Apollo Router with the --dev
flag and leverage
As an alternative to using --dev
, you can also enable query plans via the below configuration option, however, Apollo strongly discourages this as the feature may be removed or renamed in the future.
plugins:experimental.expose_query_plan: true
Log @apollo/gateway
subgraph calls
@apollo/gateway
subgraph callsTo debug queries to your subgraphs within an @apollo/gateway
instance, you can use a buildService
function
⚠️ CAUTION
While it's possible to log out the variables, Apollo strongly recommends not doing so to avoid leaking sensitive information into your logs.
class DebugDataSource extends RemoteGraphQLDataSource {willSendRequest({request}: GraphQLDataSourceProcessOptions<Record<string, any>>): void | Promise<void> {console.log(`Operation name: ${request.operationName}`);console.log(`Query body: ${request.query}`);}}const gateway = new ApolloGateway({debug: true,supergraphSdl,buildService({url}) {return new DebugDataSource({url});}});
The above snippet creates a new class called DebugDataSource
to log out the operation name and body using the willSendRequest
hook, which is called before execution.
Lastly, it also enables the debug
setting on the gateway configuration to print out query plans in the logs for further debugging if needed.