Search in sources :

Example 1 with Instrumentation

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);
}
Also used : ChainedInstrumentation(graphql.execution.instrumentation.ChainedInstrumentation) HashMap(java.util.HashMap) GraphQL(graphql.GraphQL) DataLoaderDispatcherInstrumentation(graphql.execution.instrumentation.dataloader.DataLoaderDispatcherInstrumentation) DataLoaderDispatcherInstrumentation(graphql.execution.instrumentation.dataloader.DataLoaderDispatcherInstrumentation) TracingInstrumentation(graphql.execution.instrumentation.tracing.TracingInstrumentation) ChainedInstrumentation(graphql.execution.instrumentation.ChainedInstrumentation) Instrumentation(graphql.execution.instrumentation.Instrumentation) ExecutionResult(graphql.ExecutionResult) GraphQLSchema(graphql.schema.GraphQLSchema) TracingInstrumentation(graphql.execution.instrumentation.tracing.TracingInstrumentation) DataLoaderRegistry(org.dataloader.DataLoaderRegistry) ExecutionInput.newExecutionInput(graphql.ExecutionInput.newExecutionInput) ExecutionInput(graphql.ExecutionInput)

Example 2 with Instrumentation

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;
}
Also used : GraphQLFieldDefinition(graphql.schema.GraphQLFieldDefinition) Instrumentation(graphql.execution.instrumentation.Instrumentation) ExecutionResult(graphql.ExecutionResult) InstrumentationFieldParameters(graphql.execution.instrumentation.parameters.InstrumentationFieldParameters) Field(graphql.language.Field) ExecutionTypeInfo(graphql.execution.ExecutionTypeInfo) GraphqlFieldVisibility(graphql.schema.visibility.GraphqlFieldVisibility) GraphQLObjectType(graphql.schema.GraphQLObjectType) Collections.singletonList(java.util.Collections.singletonList) List(java.util.List) ArrayList(java.util.ArrayList) Collectors.toList(java.util.stream.Collectors.toList) GraphQLList(graphql.schema.GraphQLList)

Example 3 with Instrumentation

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;
}
Also used : GraphQLList(graphql.schema.GraphQLList) InstrumentationFieldCompleteParameters(graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters) ArrayList(java.util.ArrayList) GraphQLFieldDefinition(graphql.schema.GraphQLFieldDefinition) Instrumentation(graphql.execution.instrumentation.Instrumentation) ExecutionResult(graphql.ExecutionResult) CompletableFuture(java.util.concurrent.CompletableFuture) ExecutionResultImpl(graphql.ExecutionResultImpl) ArrayList(java.util.ArrayList) List(java.util.List) Collectors.toList(java.util.stream.Collectors.toList) GraphQLList(graphql.schema.GraphQLList)

Example 4 with Instrumentation

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;
}
Also used : InstrumentationFieldCompleteParameters(graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters) GraphQLFieldDefinition(graphql.schema.GraphQLFieldDefinition) Instrumentation(graphql.execution.instrumentation.Instrumentation) ExecutionResult(graphql.ExecutionResult) Field(graphql.language.Field) GraphqlFieldVisibility(graphql.schema.visibility.GraphqlFieldVisibility) GraphQLObjectType(graphql.schema.GraphQLObjectType)

Example 5 with Instrumentation

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;
}
Also used : ArrayList(java.util.ArrayList) Instrumentation(graphql.execution.instrumentation.Instrumentation) ExecutionResult(graphql.ExecutionResult) Field(graphql.language.Field) CompletableFuture(java.util.concurrent.CompletableFuture) InstrumentationExecutionStrategyParameters(graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters) List(java.util.List) ArrayList(java.util.ArrayList) InstrumentationExecutionStrategyParameters(graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters)

Aggregations

Instrumentation (graphql.execution.instrumentation.Instrumentation)12 ExecutionResult (graphql.ExecutionResult)9 Field (graphql.language.Field)7 List (java.util.List)7 CompletableFuture (java.util.concurrent.CompletableFuture)7 ArrayList (java.util.ArrayList)6 GraphQLFieldDefinition (graphql.schema.GraphQLFieldDefinition)5 GraphQLObjectType (graphql.schema.GraphQLObjectType)4 GraphqlFieldVisibility (graphql.schema.visibility.GraphqlFieldVisibility)4 CompletionException (java.util.concurrent.CompletionException)4 ExecutionResultImpl (graphql.ExecutionResultImpl)3 InstrumentationExecutionStrategyParameters (graphql.execution.instrumentation.parameters.InstrumentationExecutionStrategyParameters)3 InstrumentationFieldParameters (graphql.execution.instrumentation.parameters.InstrumentationFieldParameters)3 GraphQLSchema (graphql.schema.GraphQLSchema)3 InstrumentationContext (graphql.execution.instrumentation.InstrumentationContext)2 SimpleInstrumentation (graphql.execution.instrumentation.SimpleInstrumentation)2 InstrumentationFieldCompleteParameters (graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters)2 InstrumentationFieldFetchParameters (graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters)2 DataFetchingEnvironment (graphql.schema.DataFetchingEnvironment)2 DataFetchingEnvironmentBuilder.newDataFetchingEnvironment (graphql.schema.DataFetchingEnvironmentBuilder.newDataFetchingEnvironment)2