use of graphql.execution.instrumentation.Instrumentation in project graphql-java by graphql-java.
the class HttpMain method handleStarWars.
private void handleStarWars(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException {
//
// this builds out the parameters we need like the graphql query from the http request
QueryParameters parameters = QueryParameters.from(httpRequest);
if (parameters.getQuery() == null) {
//
// how to handle nonsensical requests is up to your application
httpResponse.setStatus(400);
return;
}
ExecutionInput.Builder executionInput = newExecutionInput().query(parameters.getQuery()).operationName(parameters.getOperationName()).variables(parameters.getVariables());
//
// This example uses the DataLoader technique to ensure that the most efficient
// loading of data (in this case StarWars characters) happens. We pass that to data
// fetchers via the graphql context object.
//
DataLoaderRegistry dataLoaderRegistry = buildDataLoaderRegistry();
//
// the context object is something that means something to down stream code. It is instructions
// from yourself to your other code such as DataFetchers. The engine passes this on unchanged and
// makes it available to inner code
//
// the graphql guidance says :
//
// - GraphQL should be placed after all authentication middleware, so that you
// - have access to the same session and user information you would in your
// - HTTP endpoint handlers.
//
Map<String, Object> context = new HashMap<>();
context.put("YouAppSecurityClearanceLevel", "CodeRed");
context.put("YouAppExecutingUser", "Dr Nefarious");
context.put("dataloaderRegistry", dataLoaderRegistry);
executionInput.context(context);
//
// you need a schema in order to execute queries
GraphQLSchema schema = buildStarWarsSchema();
DataLoaderDispatcherInstrumentation dlInstrumentation = new DataLoaderDispatcherInstrumentation(dataLoaderRegistry, newOptions().includeStatistics(true));
Instrumentation instrumentation = new ChainedInstrumentation(asList(new TracingInstrumentation(), dlInstrumentation));
// finally you build a runtime graphql object and execute the query
GraphQL graphQL = GraphQL.newGraphQL(schema).instrumentation(instrumentation).build();
ExecutionResult executionResult = graphQL.execute(executionInput.build());
returnAsJson(httpResponse, executionResult);
}
use of graphql.execution.instrumentation.Instrumentation in project graphql-java by graphql-java.
the class BatchedExecutionStrategy method resolveField.
private CompletableFuture<List<ExecutionNode>> resolveField(ExecutionContext executionContext, ExecutionStrategyParameters parameters, String fieldName, ExecutionNode node) {
GraphQLObjectType parentType = node.getType();
List<Field> fields = node.getFields().get(fieldName);
GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, fields.get(0));
Instrumentation instrumentation = executionContext.getInstrumentation();
ExecutionTypeInfo typeInfo = parameters.getTypeInfo();
InstrumentationContext<ExecutionResult> fieldCtx = instrumentation.beginField(new InstrumentationFieldParameters(executionContext, fieldDef, typeInfo));
CompletableFuture<FetchedValues> fetchedData = fetchData(executionContext, parameters, fieldName, node, fieldDef);
CompletableFuture<List<ExecutionNode>> result = fetchedData.thenApply((fetchedValues) -> {
GraphqlFieldVisibility fieldVisibility = executionContext.getGraphQLSchema().getFieldVisibility();
Map<String, Object> argumentValues = valuesResolver.getArgumentValues(fieldVisibility, fieldDef.getArguments(), fields.get(0).getArguments(), executionContext.getVariables());
return completeValues(executionContext, fetchedValues, typeInfo, fieldName, fields, argumentValues);
});
fieldCtx.onDispatched(null);
result.whenComplete((nodes, throwable) -> fieldCtx.onCompleted(null, throwable));
return result;
}
use of graphql.execution.instrumentation.Instrumentation in project graphql-java by graphql-java.
the class ExecutionStrategy method completeValueForList.
/**
* Called to complete a list of value for a field based on a list type. This iterates the values and calls
* {@link #completeValue(ExecutionContext, ExecutionStrategyParameters)} for each value.
*
* @param executionContext contains the top level execution parameters
* @param parameters contains the parameters holding the fields to be executed and source object
* @param iterableValues the values to complete, can't be null
*
* @return an {@link ExecutionResult}
*/
protected CompletableFuture<ExecutionResult> completeValueForList(ExecutionContext executionContext, ExecutionStrategyParameters parameters, Iterable<Object> iterableValues) {
ExecutionTypeInfo typeInfo = parameters.getTypeInfo();
GraphQLList fieldType = typeInfo.castType(GraphQLList.class);
GraphQLFieldDefinition fieldDef = parameters.getTypeInfo().getFieldDefinition();
InstrumentationFieldCompleteParameters instrumentationParams = new InstrumentationFieldCompleteParameters(executionContext, parameters, fieldDef, fieldTypeInfo(parameters, fieldDef), iterableValues);
Instrumentation instrumentation = executionContext.getInstrumentation();
InstrumentationContext<ExecutionResult> completeListCtx = instrumentation.beginFieldListComplete(instrumentationParams);
CompletableFuture<List<ExecutionResult>> resultsFuture = Async.each(iterableValues, (item, index) -> {
ExecutionPath indexedPath = parameters.getPath().segment(index);
ExecutionTypeInfo wrappedTypeInfo = ExecutionTypeInfo.newTypeInfo().parentInfo(typeInfo).type(fieldType.getWrappedType()).path(indexedPath).fieldDefinition(fieldDef).build();
NonNullableFieldValidator nonNullableFieldValidator = new NonNullableFieldValidator(executionContext, wrappedTypeInfo);
ExecutionStrategyParameters newParameters = parameters.transform(builder -> builder.typeInfo(wrappedTypeInfo).nonNullFieldValidator(nonNullableFieldValidator).path(indexedPath).source(item));
return completeValue(executionContext, newParameters);
});
CompletableFuture<ExecutionResult> overallResult = new CompletableFuture<>();
completeListCtx.onDispatched(overallResult);
resultsFuture.whenComplete((results, exception) -> {
if (exception != null) {
ExecutionResult executionResult = handleNonNullException(executionContext, overallResult, exception);
completeListCtx.onCompleted(executionResult, exception);
return;
}
List<Object> completedResults = new ArrayList<>();
for (ExecutionResult completedValue : results) {
completedResults.add(completedValue.getData());
}
ExecutionResultImpl executionResult = new ExecutionResultImpl(completedResults, null);
overallResult.complete(executionResult);
});
overallResult.whenComplete(completeListCtx::onCompleted);
return overallResult;
}
use of graphql.execution.instrumentation.Instrumentation in project graphql-java by graphql-java.
the class ExecutionStrategy method completeField.
/**
* Called to complete a field based on the type of the field.
* <p>
* If the field is a scalar type, then it will be coerced and returned. However if the field type is an complex object type, then
* the execution strategy will be called recursively again to execute the fields of that type before returning.
* <p>
* Graphql fragments mean that for any give logical field can have one or more {@link Field} values associated with it
* in the query, hence the fieldList. However the first entry is representative of the field for most purposes.
*
* @param executionContext contains the top level execution parameters
* @param parameters contains the parameters holding the fields to be executed and source object
* @param fetchedValue the fetched raw value
*
* @return an {@link ExecutionResult}
*
* @throws NonNullableFieldWasNullException if a non null field resolves to a null value
*/
protected CompletableFuture<ExecutionResult> completeField(ExecutionContext executionContext, ExecutionStrategyParameters parameters, Object fetchedValue) {
Field field = parameters.getField().get(0);
GraphQLObjectType parentType = parameters.getTypeInfo().castType(GraphQLObjectType.class);
GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, field);
ExecutionTypeInfo fieldTypeInfo = fieldTypeInfo(parameters, fieldDef);
Instrumentation instrumentation = executionContext.getInstrumentation();
InstrumentationFieldCompleteParameters instrumentationParams = new InstrumentationFieldCompleteParameters(executionContext, parameters, fieldDef, fieldTypeInfo, fetchedValue);
InstrumentationContext<ExecutionResult> ctxCompleteField = instrumentation.beginFieldComplete(instrumentationParams);
GraphqlFieldVisibility fieldVisibility = executionContext.getGraphQLSchema().getFieldVisibility();
Map<String, Object> argumentValues = valuesResolver.getArgumentValues(fieldVisibility, fieldDef.getArguments(), field.getArguments(), executionContext.getVariables());
NonNullableFieldValidator nonNullableFieldValidator = new NonNullableFieldValidator(executionContext, fieldTypeInfo);
ExecutionStrategyParameters newParameters = parameters.transform(builder -> builder.typeInfo(fieldTypeInfo).arguments(argumentValues).source(fetchedValue).nonNullFieldValidator(nonNullableFieldValidator));
log.debug("'{}' completing field '{}'...", executionContext.getExecutionId(), fieldTypeInfo.getPath());
CompletableFuture<ExecutionResult> cf = completeValue(executionContext, newParameters);
ctxCompleteField.onDispatched(cf);
cf.whenComplete(ctxCompleteField::onCompleted);
return cf;
}
use of graphql.execution.instrumentation.Instrumentation in project graphql-java by graphql-java.
the class AsyncSerialExecutionStrategy method execute.
@Override
public CompletableFuture<ExecutionResult> execute(ExecutionContext executionContext, ExecutionStrategyParameters parameters) throws NonNullableFieldWasNullException {
Instrumentation instrumentation = executionContext.getInstrumentation();
InstrumentationExecutionStrategyParameters instrumentationParameters = new InstrumentationExecutionStrategyParameters(executionContext, parameters);
InstrumentationContext<ExecutionResult> executionStrategyCtx = instrumentation.beginExecutionStrategy(instrumentationParameters);
Map<String, List<Field>> fields = parameters.getFields();
List<String> fieldNames = new ArrayList<>(fields.keySet());
CompletableFuture<List<ExecutionResult>> resultsFuture = Async.eachSequentially(fieldNames, (fieldName, index, prevResults) -> {
List<Field> currentField = fields.get(fieldName);
ExecutionPath fieldPath = parameters.getPath().segment(fieldName);
ExecutionStrategyParameters newParameters = parameters.transform(builder -> builder.field(currentField).path(fieldPath));
return resolveField(executionContext, newParameters);
});
CompletableFuture<ExecutionResult> overallResult = new CompletableFuture<>();
executionStrategyCtx.onDispatched(overallResult);
resultsFuture.whenComplete(handleResults(executionContext, fieldNames, overallResult));
overallResult.whenComplete(executionStrategyCtx::onCompleted);
return overallResult;
}
Aggregations