graphql.execution.instrumentation.Instrumentation Maven / Gradle / Ivy
package graphql.execution.instrumentation;
import graphql.ExecutionInput;
import graphql.ExecutionResult;
import graphql.PublicSpi;
import graphql.execution.ExecutionContext;
import graphql.execution.instrumentation.parameters.InstrumentationCreateStateParameters;
import graphql.execution.instrumentation.parameters.InstrumentationExecuteOperationParameters;
import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters;
import graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters;
import graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters;
import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters;
import graphql.execution.instrumentation.parameters.InstrumentationFieldParameters;
import graphql.execution.instrumentation.parameters.InstrumentationValidationParameters;
import graphql.language.Document;
import graphql.schema.DataFetcher;
import graphql.schema.GraphQLSchema;
import graphql.validation.ValidationError;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import static graphql.execution.instrumentation.SimpleInstrumentationContext.noOp;
/**
* Provides the capability to instrument the execution steps of a GraphQL query.
*
* For example you might want to track which fields are taking the most time to fetch from the backing database
* or log what fields are being asked for.
*
* Remember that graphql calls can cross threads so make sure you think about the thread safety of any instrumentation
* code when you are writing it.
*
* Each step gives back an {@link graphql.execution.instrumentation.InstrumentationContext} object. This has two callbacks on it,
* one for the step is `dispatched` and one for when the step has `completed`. This is done because many of the "steps" are asynchronous
* operations such as fetching data and resolving it into objects.
*/
@PublicSpi
public interface Instrumentation {
/**
* This will be called just before execution to create an object that is given back to all instrumentation methods
* to allow them to have per execution request state
*
* @return a state object that is passed to each method
*/
default InstrumentationState createState() {
return null;
}
/**
* This will be called just before execution to create an object that is given back to all instrumentation methods
* to allow them to have per execution request state
*
* @param parameters the parameters to this step
*
* @return a state object that is passed to each method
*/
default InstrumentationState createState(InstrumentationCreateStateParameters parameters) {
return createState();
}
/**
* This is called right at the start of query execution and its the first step in the instrumentation chain.
*
* @param parameters the parameters to this step
*
* @return a non null {@link InstrumentationContext} object that will be called back when the step ends
*/
InstrumentationContext beginExecution(InstrumentationExecutionParameters parameters);
/**
* This is called just before a query is parsed.
*
* @param parameters the parameters to this step
*
* @return a non null {@link InstrumentationContext} object that will be called back when the step ends
*/
InstrumentationContext beginParse(InstrumentationExecutionParameters parameters);
/**
* This is called just before the parsed query document is validated.
*
* @param parameters the parameters to this step
*
* @return a non null {@link InstrumentationContext} object that will be called back when the step ends
*/
InstrumentationContext> beginValidation(InstrumentationValidationParameters parameters);
/**
* This is called just before the execution of the query operation is started.
*
* @param parameters the parameters to this step
*
* @return a non null {@link InstrumentationContext} object that will be called back when the step ends
*/
InstrumentationContext beginExecuteOperation(InstrumentationExecuteOperationParameters parameters);
/**
* This is called each time an {@link graphql.execution.ExecutionStrategy} is invoked, which may be multiple times
* per query as the engine recursively descends down over the query.
*
* @param parameters the parameters to this step
*
* @return a non null {@link InstrumentationContext} object that will be called back when the step ends
*/
ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters);
/**
* This is called each time a subscription field produces a new reactive stream event value and it needs to be mapped over via the graphql field subselection.
*
* @param parameters the parameters to this step
*
* @return a non null {@link InstrumentationContext} object that will be called back when the step ends
*/
default InstrumentationContext beginSubscribedFieldEvent(InstrumentationFieldParameters parameters) {
return noOp();
}
/**
* This is called just before a field is resolved into a value.
*
* @param parameters the parameters to this step
*
* @return a non null {@link InstrumentationContext} object that will be called back when the step ends
*/
InstrumentationContext beginField(InstrumentationFieldParameters parameters);
/**
* This is called just before a field {@link DataFetcher} is invoked.
*
* @param parameters the parameters to this step
*
* @return a non null {@link InstrumentationContext} object that will be called back when the step ends
*/
InstrumentationContext