graphql.ExecutionInput Maven / Gradle / Ivy
package graphql;
import graphql.collect.ImmutableKit;
import graphql.execution.ExecutionId;
import graphql.execution.RawVariables;
import org.dataloader.DataLoaderRegistry;
import java.util.Locale;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.UnaryOperator;
import static graphql.Assert.assertNotNull;
import static graphql.execution.instrumentation.dataloader.EmptyDataLoaderRegistryInstance.EMPTY_DATALOADER_REGISTRY;
/**
* This represents the series of values that can be input on a graphql query execution
*/
@PublicApi
public class ExecutionInput {
private final String query;
private final String operationName;
private final Object context;
private final GraphQLContext graphQLContext;
private final Object localContext;
private final Object root;
private final RawVariables rawVariables;
private final Map extensions;
private final DataLoaderRegistry dataLoaderRegistry;
private final ExecutionId executionId;
private final Locale locale;
@Internal
private ExecutionInput(Builder builder) {
this.query = assertNotNull(builder.query, () -> "query can't be null");
this.operationName = builder.operationName;
this.context = builder.context;
this.graphQLContext = assertNotNull(builder.graphQLContext);
this.root = builder.root;
this.rawVariables = builder.rawVariables;
this.dataLoaderRegistry = builder.dataLoaderRegistry;
this.executionId = builder.executionId;
this.locale = builder.locale != null ? builder.locale : Locale.getDefault(); // always have a locale in place
this.localContext = builder.localContext;
this.extensions = builder.extensions;
}
/**
* @return the query text
*/
public String getQuery() {
return query;
}
/**
* @return the name of the query operation
*/
public String getOperationName() {
return operationName;
}
/**
* The legacy context object has been deprecated in favour of the more shareable
* {@link #getGraphQLContext()}
*
* @return the context object to pass to all data fetchers
*
* @deprecated - use {@link #getGraphQLContext()}
*/
@Deprecated(since = "2021-07-05")
public Object getContext() {
return context;
}
/**
* @return the shared {@link GraphQLContext} object to pass to all data fetchers
*/
public GraphQLContext getGraphQLContext() {
return graphQLContext;
}
/**
* @return the local context object to pass to all top level (i.e. query, mutation, subscription) data fetchers
*/
public Object getLocalContext() {
return localContext;
}
/**
* @return the root object to start the query execution on
*/
public Object getRoot() {
return root;
}
/**
* @return a map of raw variables that can be referenced via $syntax in the query.
*/
public Map getVariables() {
return rawVariables.toMap();
}
/**
* @return a map of raw variables that can be referenced via $syntax in the query.
*/
public RawVariables getRawVariables() {
return rawVariables;
}
/**
* @return the data loader registry associated with this execution
*/
public DataLoaderRegistry getDataLoaderRegistry() {
return dataLoaderRegistry;
}
/**
* @return Id that will be/was used to execute this operation.
*/
public ExecutionId getExecutionId() {
return executionId;
}
/**
* This returns the locale of this operation.
*
* @return the locale of this operation
*/
public Locale getLocale() {
return locale;
}
/**
* @return a map of extension values that can be sent in to a request
*/
public Map getExtensions() {
return extensions;
}
/**
* This helps you transform the current ExecutionInput object into another one by starting a builder with all
* the current values and allows you to transform it how you want.
*
* @param builderConsumer the consumer code that will be given a builder to transform
*
* @return a new ExecutionInput object based on calling build on that builder
*/
public ExecutionInput transform(Consumer builderConsumer) {
Builder builder = new Builder()
.query(this.query)
.operationName(this.operationName)
.context(this.context)
.transfer(this.graphQLContext)
.localContext(this.localContext)
.root(this.root)
.dataLoaderRegistry(this.dataLoaderRegistry)
.variables(this.rawVariables.toMap())
.extensions(this.extensions)
.executionId(this.executionId)
.locale(this.locale);
builderConsumer.accept(builder);
return builder.build();
}
@Override
public String toString() {
return "ExecutionInput{" +
"query='" + query + '\'' +
", operationName='" + operationName + '\'' +
", context=" + context +
", graphQLContext=" + graphQLContext +
", root=" + root +
", rawVariables=" + rawVariables +
", dataLoaderRegistry=" + dataLoaderRegistry +
", executionId= " + executionId +
", locale= " + locale +
'}';
}
/**
* @return a new builder of ExecutionInput objects
*/
public static Builder newExecutionInput() {
return new Builder();
}
/**
* Creates a new builder of ExecutionInput objects with the given query
*
* @param query the query to execute
*
* @return a new builder of ExecutionInput objects
*/
public static Builder newExecutionInput(String query) {
return new Builder().query(query);
}
public static class Builder {
private String query;
private String operationName;
private GraphQLContext graphQLContext = GraphQLContext.newContext().build();
private Object context = graphQLContext; // we make these the same object on purpose - legacy code will get the same object if this change nothing
private Object localContext;
private Object root;
private RawVariables rawVariables = RawVariables.emptyVariables();
public Map extensions = ImmutableKit.emptyMap();
//
// this is important - it allows code to later known if we never really set a dataloader and hence it can optimize
// dataloader field tracking away.
//
private DataLoaderRegistry dataLoaderRegistry = EMPTY_DATALOADER_REGISTRY;
private Locale locale = Locale.getDefault();
private ExecutionId executionId;
public Builder query(String query) {
this.query = assertNotNull(query, () -> "query can't be null");
return this;
}
public Builder operationName(String operationName) {
this.operationName = operationName;
return this;
}
/**
* A default one will be assigned, but you can set your own.
*
* @param executionId an execution id object
*
* @return this builder
*/
public Builder executionId(ExecutionId executionId) {
this.executionId = executionId;
return this;
}
/**
* Sets the locale to use for this operation
*
* @param locale the locale to use
*
* @return this builder
*/
public Builder locale(Locale locale) {
this.locale = locale;
return this;
}
/**
* Sets initial localContext in root data fetchers
*
* @param localContext the local context to use
*
* @return this builder
*/
public Builder localContext(Object localContext) {
this.localContext = localContext;
return this;
}
/**
* The legacy context object
*
* @param context the context object to use
*
* @return this builder
*
* @deprecated - the {@link ExecutionInput#getGraphQLContext()} is a fixed mutable instance now
*/
@Deprecated(since = "2021-07-05")
public Builder context(Object context) {
this.context = context;
return this;
}
/**
* This will give you a builder of {@link GraphQLContext} and any values you set will be copied
* into the underlying {@link GraphQLContext} of this execution input
*
* @param builderFunction a builder function you can use to put values into the context
*
* @return this builder
*/
public Builder graphQLContext(Consumer builderFunction) {
GraphQLContext.Builder builder = GraphQLContext.newContext();
builderFunction.accept(builder);
this.graphQLContext.putAll(builder);
return this;
}
/**
* This will put all the values from the map into the underlying {@link GraphQLContext} of this execution input
*
* @param mapOfContext a map of values to put in the context
*
* @return this builder
*/
public Builder graphQLContext(Map, Object> mapOfContext) {
this.graphQLContext.putAll(mapOfContext);
return this;
}
// hidden on purpose
private Builder transfer(GraphQLContext graphQLContext) {
this.graphQLContext = Assert.assertNotNull(graphQLContext);
return this;
}
public Builder root(Object root) {
this.root = root;
return this;
}
/**
* Adds raw (not coerced) variables
*
* @param rawVariables the map of raw variables
*
* @return this builder
*/
public Builder variables(Map rawVariables) {
assertNotNull(rawVariables, () -> "variables map can't be null");
this.rawVariables = RawVariables.of(rawVariables);
return this;
}
public Builder extensions(Map extensions) {
this.extensions = assertNotNull(extensions, () -> "extensions map can't be null");
return this;
}
/**
* You should create new {@link org.dataloader.DataLoaderRegistry}s and new {@link org.dataloader.DataLoader}s for each execution. Do not
* re-use
* instances as this will create unexpected results.
*
* @param dataLoaderRegistry a registry of {@link org.dataloader.DataLoader}s
*
* @return this builder
*/
public Builder dataLoaderRegistry(DataLoaderRegistry dataLoaderRegistry) {
this.dataLoaderRegistry = assertNotNull(dataLoaderRegistry);
return this;
}
public ExecutionInput build() {
return new ExecutionInput(this);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy