Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 17 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,25 +189,26 @@ GraphQLInterfaceType comicCharacter = newInterface()

##### Creating a new Union Type

Example: (a snippet from [here](src/test/groovy/graphql/GarfieldSchema.java))
Example:
Example:
```java
GraphQLUnionType PetType = newUnionType()
.name("Pet")
.possibleType(CatType)
.possibleType(DogType)
.typeResolver(new TypeResolver() {
@Override
public GraphQLObjectType getType(Object object) {
if (object instanceof Cat) {
return CatType;
}
if (object instanceof Dog) {
return DogType;
.name("Pet")
.possibleType(CatType)
.possibleType(DogType)
.typeResolver(new TypeResolver() {
@Override
public GraphQLObjectType getType(TypeResolutionEnvironment env) {
if (env.getObject() instanceof Cat) {
return CatType;
}
if (env.getObject() instanceof Dog) {
return DogType;
}
return null;
}
return null;
}
})
.build();
})
.build();

```

Expand Down
47 changes: 47 additions & 0 deletions src/main/java/graphql/TypeResolutionEnvironment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package graphql;

import graphql.language.Field;
import graphql.schema.GraphQLSchema;
import graphql.schema.GraphQLType;

import java.util.Map;

/**
* See {@link graphql.schema.TypeResolver#getType(TypeResolutionEnvironment)} for how this is used
*/
public class TypeResolutionEnvironment {

private final Object object;
private final Map<String, Object> arguments;
private final Field field;
private final GraphQLType fieldType;
private final GraphQLSchema schema;

public TypeResolutionEnvironment(Object object, Map<String, Object> arguments, Field field, GraphQLType fieldType, GraphQLSchema schema) {
this.object = object;
this.arguments = arguments;
this.field = field;
this.fieldType = fieldType;
this.schema = schema;
}

public Object getObject() {
return object;
}

public Map<String, Object> getArguments() {
return arguments;
}

public Field getField() {
return field;
}

public GraphQLType getFieldType() {
return fieldType;
}

public GraphQLSchema getSchema() {
return schema;
}
}
16 changes: 14 additions & 2 deletions src/main/java/graphql/execution/ExecutionParameters.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@
public class ExecutionParameters {
private final TypeInfo typeInfo;
private final Object source;
private final Map<String, Object> arguments;
private final Map<String, List<Field>> fields;

private ExecutionParameters(TypeInfo typeInfo, Object source, Map<String, List<Field>> fields) {
private ExecutionParameters(TypeInfo typeInfo, Object source, Map<String, List<Field>> fields, Map<String, Object> arguments) {
this.typeInfo = assertNotNull(typeInfo, "");
this.fields = assertNotNull(fields, "");
this.source = source;
this.arguments = arguments;
}

public TypeInfo typeInfo() {
Expand All @@ -33,6 +35,10 @@ public Map<String, List<Field>> fields() {
return fields;
}

public Map<String, Object> arguments() {
return arguments;
}

public static Builder newParameters() {
return new Builder();
}
Expand All @@ -47,6 +53,7 @@ public static class Builder {
TypeInfo typeInfo;
Object source;
Map<String, List<Field>> fields;
Map<String, Object> arguments;

public Builder typeInfo(TypeInfo type) {
this.typeInfo = type;
Expand All @@ -68,8 +75,13 @@ public Builder source(Object source) {
return this;
}

public Builder arguments(Map<String, Object> arguments) {
this.arguments = arguments;
return this;
}

public ExecutionParameters build() {
return new ExecutionParameters(typeInfo, source, fields);
return new ExecutionParameters(typeInfo, source, fields, arguments);
}
}
}
37 changes: 26 additions & 11 deletions src/main/java/graphql/execution/ExecutionStrategy.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import graphql.ExecutionResult;
import graphql.ExecutionResultImpl;
import graphql.GraphQLException;
import graphql.TypeResolutionEnvironment;
import graphql.execution.instrumentation.Instrumentation;
import graphql.execution.instrumentation.InstrumentationContext;
import graphql.execution.instrumentation.parameters.FieldFetchParameters;
Expand Down Expand Up @@ -101,6 +102,7 @@ protected ExecutionResult resolveField(ExecutionContext executionContext, Execut
ExecutionParameters newParameters = ExecutionParameters.newParameters()
.typeInfo(fieldType)
.fields(parameters.fields())
.arguments(argumentValues)
.source(resolvedValue).build();

ExecutionResult result = completeValue(executionContext, newParameters, fields);
Expand Down Expand Up @@ -133,9 +135,22 @@ protected ExecutionResult completeValue(ExecutionContext executionContext, Execu

GraphQLObjectType resolvedType;
if (fieldType instanceof GraphQLInterfaceType) {
resolvedType = resolveType((GraphQLInterfaceType) fieldType, result);
TypeResolutionParameters resolutionParams = TypeResolutionParameters.newParameters()
.graphQLInterfaceType((GraphQLInterfaceType) fieldType)
.field(fields.get(0))
.value(parameters.source())
.argumentValues(parameters.arguments())
.schema(executionContext.getGraphQLSchema()).build();
resolvedType = resolveTypeForInterface(resolutionParams);

} else if (fieldType instanceof GraphQLUnionType) {
resolvedType = resolveType((GraphQLUnionType) fieldType, result);
TypeResolutionParameters resolutionParams = TypeResolutionParameters.newParameters()
.graphQLUnionType((GraphQLUnionType) fieldType)
.field(fields.get(0))
.value(parameters.source())
.argumentValues(parameters.arguments())
.schema(executionContext.getGraphQLSchema()).build();
resolvedType = resolveTypeForUnion(resolutionParams);
} else {
resolvedType = (GraphQLObjectType) fieldType;
}
Expand Down Expand Up @@ -165,18 +180,20 @@ private Iterable<Object> toIterable(Object result) {
return (Iterable<Object>) result;
}

protected GraphQLObjectType resolveType(GraphQLInterfaceType graphQLInterfaceType, Object value) {
GraphQLObjectType result = graphQLInterfaceType.getTypeResolver().getType(value);
protected GraphQLObjectType resolveTypeForInterface(TypeResolutionParameters params) {
TypeResolutionEnvironment env = new TypeResolutionEnvironment(params.getValue(), params.getArgumentValues(), params.getField(), params.getGraphQLInterfaceType(), params.getSchema());
GraphQLObjectType result = params.getGraphQLInterfaceType().getTypeResolver().getType(env);
if (result == null) {
throw new GraphQLException("could not determine type");
throw new GraphQLException("Could not determine the exact type of " + params.getGraphQLInterfaceType().getName());
}
return result;
}

protected GraphQLObjectType resolveType(GraphQLUnionType graphQLUnionType, Object value) {
GraphQLObjectType result = graphQLUnionType.getTypeResolver().getType(value);
protected GraphQLObjectType resolveTypeForUnion(TypeResolutionParameters params) {
TypeResolutionEnvironment env = new TypeResolutionEnvironment(params.getValue(), params.getArgumentValues(), params.getField(), params.getGraphQLUnionType(), params.getSchema());
GraphQLObjectType result = params.getGraphQLUnionType().getTypeResolver().getType(env);
if (result == null) {
throw new GraphQLException("could not determine type");
throw new GraphQLException("Could not determine the exact type of " + params.getGraphQLUnionType().getName());
}
return result;
}
Expand Down Expand Up @@ -226,10 +243,8 @@ protected GraphQLFieldDefinition getFieldDef(GraphQLSchema schema, GraphQLObject

GraphQLFieldDefinition fieldDefinition = parentType.getFieldDefinition(field.getName());
if (fieldDefinition == null) {
throw new GraphQLException("unknown field " + field.getName());
throw new GraphQLException("Unknown field " + field.getName());
}
return fieldDefinition;
}


}
100 changes: 100 additions & 0 deletions src/main/java/graphql/execution/TypeResolutionParameters.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package graphql.execution;

import java.util.Map;

import graphql.language.Field;
import graphql.schema.GraphQLInterfaceType;
import graphql.schema.GraphQLSchema;
import graphql.schema.GraphQLUnionType;

public class TypeResolutionParameters {

private final GraphQLInterfaceType graphQLInterfaceType;
private final GraphQLUnionType graphQLUnionType;
private final Field field;
private final Object value;
private final Map<String, Object> argumentValues;
private final GraphQLSchema schema;

private TypeResolutionParameters(GraphQLInterfaceType graphQLInterfaceType, GraphQLUnionType graphQLUnionType,
Field field, Object value, Map<String, Object> argumentValues, GraphQLSchema schema) {
this.graphQLInterfaceType = graphQLInterfaceType;
this.graphQLUnionType = graphQLUnionType;
this.field = field;
this.value = value;
this.argumentValues = argumentValues;
this.schema = schema;
}

public GraphQLInterfaceType getGraphQLInterfaceType() {
return graphQLInterfaceType;
}

public GraphQLUnionType getGraphQLUnionType() {
return graphQLUnionType;
}

public Field getField() {
return field;
}

public Object getValue() {
return value;
}

public Map<String, Object> getArgumentValues() {
return argumentValues;
}

public GraphQLSchema getSchema() {
return schema;
}

public static Builder newParameters() {
return new Builder();
}

public static class Builder {

private Field field;
private GraphQLInterfaceType graphQLInterfaceType;
private GraphQLUnionType graphQLUnionType;
private Object value;
private Map<String, Object> argumentValues;
private GraphQLSchema schema;

public Builder field(Field field) {
this.field = field;
return this;
}

public Builder graphQLInterfaceType(GraphQLInterfaceType graphQLInterfaceType) {
this.graphQLInterfaceType = graphQLInterfaceType;
return this;
}

public Builder graphQLUnionType(GraphQLUnionType graphQLUnionType) {
this.graphQLUnionType = graphQLUnionType;
return this;
}

public Builder value(Object value) {
this.value = value;
return this;
}

public Builder argumentValues(Map<String, Object> argumentValues) {
this.argumentValues = argumentValues;
return this;
}

public Builder schema(GraphQLSchema schema) {
this.schema = schema;
return this;
}

public TypeResolutionParameters build() {
return new TypeResolutionParameters(graphQLInterfaceType, graphQLUnionType, field, value, argumentValues, schema);
}
}
}
Loading