Field field = parameters.getField().getSingleField(); GraphQLObjectType parentType = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType(); GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, field); ExecutionStepInfo executionStepInfo = createExecutionStepInfo(executionContext, parameters, fieldDef, parentType); FieldValueInfo fieldValueInfo = completeValue(executionContext, newParameters);
protected ExecutionResult handleNonNullException(ExecutionContext executionContext, CompletableFuture<ExecutionResult> result, Throwable e) { ExecutionResult executionResult = null; List<GraphQLError> errors = new ArrayList<>(executionContext.getErrors()); Throwable underlyingException = e; if (e instanceof CompletionException) { underlyingException = e.getCause(); } if (underlyingException instanceof NonNullableFieldWasNullException) { assertNonNullFieldPrecondition((NonNullableFieldWasNullException) underlyingException, result); if (!result.isDone()) { executionResult = new ExecutionResultImpl(null, errors); result.complete(executionResult); } } else if (underlyingException instanceof AbortExecutionException) { AbortExecutionException abortException = (AbortExecutionException) underlyingException; executionResult = abortException.toExecutionResult(); result.complete(executionResult); } else { result.completeExceptionally(e); } return executionResult; }
/** * Called to fetch a value for a field and its extra runtime info and resolve it further in terms of the graphql query. This will call * #fetchField followed by #completeField and the completed {@link graphql.execution.FieldValueInfo} is returned. * <p> * An execution strategy can iterate the fields to be executed and call this method for each one * <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 * * @return a promise to a {@link FieldValueInfo} * * @throws NonNullableFieldWasNullException in the {@link FieldValueInfo#getFieldValue()} future if a non null field resolves to a null value */ protected CompletableFuture<FieldValueInfo> resolveFieldWithInfo(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { GraphQLFieldDefinition fieldDef = getFieldDef(executionContext, parameters, parameters.getField().getSingleField()); Instrumentation instrumentation = executionContext.getInstrumentation(); InstrumentationContext<ExecutionResult> fieldCtx = instrumentation.beginField( new InstrumentationFieldParameters(executionContext, fieldDef, createExecutionStepInfo(executionContext, parameters, fieldDef, null)) ); CompletableFuture<FetchedValue> fetchFieldFuture = fetchField(executionContext, parameters); CompletableFuture<FieldValueInfo> result = fetchFieldFuture.thenApply((fetchedValue) -> completeField(executionContext, parameters, fetchedValue)); CompletableFuture<ExecutionResult> executionResultFuture = result.thenCompose(FieldValueInfo::getFieldValue); fieldCtx.onDispatched(executionResultFuture); executionResultFuture.whenComplete(fieldCtx::onCompleted); return result; }
fieldValue = completeValueForNull(parameters); return FieldValueInfo.newFieldValueInfo(NULL).fieldValue(fieldValue).build(); } else if (isList(fieldType)) { return completeValueForList(executionContext, parameters, result); } else if (fieldType instanceof GraphQLScalarType) { fieldValue = completeValueForScalar(executionContext, parameters, (GraphQLScalarType) fieldType, result); return FieldValueInfo.newFieldValueInfo(SCALAR).fieldValue(fieldValue).build(); } else if (fieldType instanceof GraphQLEnumType) { fieldValue = completeValueForEnum(executionContext, parameters, (GraphQLEnumType) fieldType, result); return FieldValueInfo.newFieldValueInfo(ENUM).fieldValue(fieldValue).build(); resolvedObjectType = resolveType(executionContext, parameters, fieldType); fieldValue = completeValueForObject(executionContext, parameters, resolvedObjectType, result); } catch (UnresolvedTypeException ex) { handleUnresolvedTypeProblem(executionContext, parameters, ex);
/** * 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 result the result to complete, raw result * * @return a {@link FieldValueInfo} */ protected FieldValueInfo completeValueForList(ExecutionContext executionContext, ExecutionStrategyParameters parameters, Object result) { Iterable<Object> resultIterable = toIterable(executionContext, parameters, result); try { resultIterable = parameters.getNonNullFieldValidator().validate(parameters.getPath(), resultIterable); } catch (NonNullableFieldWasNullException e) { return FieldValueInfo.newFieldValueInfo(LIST).fieldValue(exceptionallyCompletedFuture(e)).build(); } if (resultIterable == null) { return FieldValueInfo.newFieldValueInfo(LIST).fieldValue(completedFuture(new ExecutionResultImpl(null, null))).build(); } return completeValueForList(executionContext, parameters, resultIterable); }
MergedField field = parameters.getField(); GraphQLObjectType parentType = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType(); GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, field.getSingleField()); ExecutionStepInfo executionStepInfo = createExecutionStepInfo(executionContext, parameters, fieldDef, parentType); fetchCtx.onCompleted(result, exception); if (exception != null) { handleFetchingException(executionContext, parameters, environment, exception); return null; } else { .thenApply(result -> unboxPossibleDataFetcherResult(executionContext, parameters, result));
GraphQLObjectType fieldContainer = parameters.getExecutionStepInfo().getFieldContainer(); InstrumentationFieldCompleteParameters instrumentationParams = new InstrumentationFieldCompleteParameters(executionContext, parameters, fieldDef, createExecutionStepInfo(executionContext, parameters, fieldDef, fieldContainer), values); Instrumentation instrumentation = executionContext.getInstrumentation(); .source(item) ); fieldValueInfos.add(completeValue(executionContext, newParameters)); index++; ExecutionResult executionResult = handleNonNullException(executionContext, overallResult, exception); completeListCtx.onCompleted(executionResult, exception); return;
@Override protected ExecutionResult completeValue(ExecutionContext executionContext, GraphQLType fieldType, List<Field> fields, Object result) { if (result instanceof Observable) { return new RxExecutionResult(((Observable<?>) result).map(r -> super.completeValue(executionContext, fieldType, fields, r)), null); } return super.completeValue(executionContext, fieldType, fields, result); }
result = executionStrategy.execute(executionContext, parameters); } catch (NonNullableFieldWasNullException e) {
fieldValue = completeValueForNull(parameters); return FieldValueInfo.newFieldValueInfo(NULL).fieldValue(fieldValue).build(); } else if (isList(fieldType)) { return completeValueForList(executionContext, parameters, result); } else if (fieldType instanceof GraphQLScalarType) { fieldValue = completeValueForScalar(executionContext, parameters, (GraphQLScalarType) fieldType, result); return FieldValueInfo.newFieldValueInfo(SCALAR).fieldValue(fieldValue).build(); } else if (fieldType instanceof GraphQLEnumType) { fieldValue = completeValueForEnum(executionContext, parameters, (GraphQLEnumType) fieldType, result); return FieldValueInfo.newFieldValueInfo(ENUM).fieldValue(fieldValue).build(); resolvedObjectType = resolveType(executionContext, parameters, fieldType); fieldValue = completeValueForObject(executionContext, parameters, resolvedObjectType, result); } catch (UnresolvedTypeException ex) { handleUnresolvedTypeProblem(executionContext, parameters, ex);
MergedField field = parameters.getField(); GraphQLObjectType parentType = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType(); GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, field.getSingleField()); ExecutionStepInfo executionStepInfo = createExecutionStepInfo(executionContext, parameters, fieldDef, parentType); fetchCtx.onCompleted(result, exception); if (exception != null) { handleFetchingException(executionContext, parameters, environment, exception); return null; } else { .thenApply(result -> unboxPossibleDataFetcherResult(executionContext, parameters, result));
GraphQLObjectType fieldContainer = parameters.getExecutionStepInfo().getFieldContainer(); InstrumentationFieldCompleteParameters instrumentationParams = new InstrumentationFieldCompleteParameters(executionContext, parameters, fieldDef, createExecutionStepInfo(executionContext, parameters, fieldDef, fieldContainer), values); Instrumentation instrumentation = executionContext.getInstrumentation(); .source(item) ); fieldValueInfos.add(completeValue(executionContext, newParameters)); index++; ExecutionResult executionResult = handleNonNullException(executionContext, overallResult, exception); completeListCtx.onCompleted(executionResult, exception); return;
@Override protected ExecutionResult completeValue(ExecutionContext executionContext, GraphQLType fieldType, List<Field> fields, Object result) { if (result instanceof Observable) { return new GraphQLRxExecutionResult(((Observable<?>) result).map(r -> super.completeValue(executionContext, fieldType, fields, r)), null); } return super.completeValue(executionContext, fieldType, fields, result); }
/** * Called to turn an java object value into an graphql object value * * @param executionContext contains the top level execution parameters * @param parameters contains the parameters holding the fields to be executed and source object * @param resolvedObjectType the resolved object type * @param result the result to be coerced * * @return a promise to an {@link ExecutionResult} */ protected CompletableFuture<ExecutionResult> completeValueForObject(ExecutionContext executionContext, ExecutionStrategyParameters parameters, GraphQLObjectType resolvedObjectType, Object result) { ExecutionStepInfo executionStepInfo = parameters.getExecutionStepInfo(); FieldCollectorParameters collectorParameters = newParameters() .schema(executionContext.getGraphQLSchema()) .objectType(resolvedObjectType) .fragments(executionContext.getFragmentsByName()) .variables(executionContext.getVariables()) .build(); MergedSelectionSet subFields = fieldCollector.collectFields(collectorParameters, parameters.getField()); ExecutionStepInfo newExecutionStepInfo = executionStepInfo.changeTypeWithPreservedNonNull(resolvedObjectType); NonNullableFieldValidator nonNullableFieldValidator = new NonNullableFieldValidator(executionContext, newExecutionStepInfo); ExecutionStrategyParameters newParameters = parameters.transform(builder -> builder.executionStepInfo(newExecutionStepInfo) .fields(subFields) .nonNullFieldValidator(nonNullableFieldValidator) .source(result) ); // Calling this from the executionContext to ensure we shift back from mutation strategy to the query strategy. return executionContext.getQueryStrategy().execute(executionContext, newParameters); }
/** * 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 result the result to complete, raw result * * @return a {@link FieldValueInfo} */ protected FieldValueInfo completeValueForList(ExecutionContext executionContext, ExecutionStrategyParameters parameters, Object result) { Iterable<Object> resultIterable = toIterable(executionContext, parameters, result); try { resultIterable = parameters.getNonNullFieldValidator().validate(parameters.getPath(), resultIterable); } catch (NonNullableFieldWasNullException e) { return FieldValueInfo.newFieldValueInfo(LIST).fieldValue(exceptionallyCompletedFuture(e)).build(); } if (resultIterable == null) { return FieldValueInfo.newFieldValueInfo(LIST).fieldValue(completedFuture(new ExecutionResultImpl(null, null))).build(); } return completeValueForList(executionContext, parameters, resultIterable); }
Field field = parameters.getField().getSingleField(); GraphQLObjectType parentType = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType(); GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, field); ExecutionStepInfo executionStepInfo = createExecutionStepInfo(executionContext, parameters, fieldDef, parentType); FieldValueInfo fieldValueInfo = completeValue(executionContext, newParameters);
/** * Called to fetch a value for a field and its extra runtime info and resolve it further in terms of the graphql query. This will call * #fetchField followed by #completeField and the completed {@link graphql.execution.FieldValueInfo} is returned. * <p> * An execution strategy can iterate the fields to be executed and call this method for each one * <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 * * @return a promise to a {@link FieldValueInfo} * * @throws NonNullableFieldWasNullException in the {@link FieldValueInfo#getFieldValue()} future if a non null field resolves to a null value */ protected CompletableFuture<FieldValueInfo> resolveFieldWithInfo(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { GraphQLFieldDefinition fieldDef = getFieldDef(executionContext, parameters, parameters.getField().getSingleField()); Instrumentation instrumentation = executionContext.getInstrumentation(); InstrumentationContext<ExecutionResult> fieldCtx = instrumentation.beginField( new InstrumentationFieldParameters(executionContext, fieldDef, createExecutionStepInfo(executionContext, parameters, fieldDef, null)) ); CompletableFuture<FetchedValue> fetchFieldFuture = fetchField(executionContext, parameters); CompletableFuture<FieldValueInfo> result = fetchFieldFuture.thenApply((fetchedValue) -> completeField(executionContext, parameters, fetchedValue)); CompletableFuture<ExecutionResult> executionResultFuture = result.thenCompose(FieldValueInfo::getFieldValue); fieldCtx.onDispatched(executionResultFuture); executionResultFuture.whenComplete(fieldCtx::onCompleted); return result; }
return super.completeValue(context, parameters, fields);
private ExecutionResult executeOperation( ExecutionContext executionContext, Object root, OperationDefinition operationDefinition) { GraphQLObjectType operationRootType = getOperationRootType(executionContext.getGraphQLSchema(), executionContext.getOperationDefinition()); Map<String, List<Field>> fields = new LinkedHashMap<String, List<Field>>(); fieldCollector.collectFields(executionContext, operationRootType, operationDefinition.getSelectionSet(), new ArrayList<String>(), fields); if (operationDefinition.getOperation() == OperationDefinition.Operation.MUTATION) { return new GraphQLDefaultRxExecutionStrategy(graphQLSchemaHolder, maxQueryDepth, maxQueryComplexity) .execute(executionContext, operationRootType, root, fields); } else { return strategy.execute(executionContext, operationRootType, root, fields); } } }
protected ExecutionResult handleNonNullException(ExecutionContext executionContext, CompletableFuture<ExecutionResult> result, Throwable e) { ExecutionResult executionResult = null; List<GraphQLError> errors = new ArrayList<>(executionContext.getErrors()); Throwable underlyingException = e; if (e instanceof CompletionException) { underlyingException = e.getCause(); } if (underlyingException instanceof NonNullableFieldWasNullException) { assertNonNullFieldPrecondition((NonNullableFieldWasNullException) underlyingException, result); if (!result.isDone()) { executionResult = new ExecutionResultImpl(null, errors); result.complete(executionResult); } } else if (underlyingException instanceof AbortExecutionException) { AbortExecutionException abortException = (AbortExecutionException) underlyingException; executionResult = abortException.toExecutionResult(); result.complete(executionResult); } else { result.completeExceptionally(e); } return executionResult; }