Skip to content

Commit

Permalink
Merge pull request #85 from apollographql/sachin/graphql-java-v16
Browse files Browse the repository at this point in the history
graphql-java-support: Bump graphql-java to v16.1
  • Loading branch information
sachindshinde committed Jan 21, 2021
2 parents 045a9ef + 999e633 commit e612aa8
Show file tree
Hide file tree
Showing 8 changed files with 215 additions and 127 deletions.
5 changes: 5 additions & 0 deletions graphql-java-support/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.apollographql.federation.graphqljava;

import graphql.language.DirectiveDefinition;
import graphql.language.FieldDefinition;
import graphql.language.ObjectTypeDefinition;
import graphql.language.TypeDefinition;
import graphql.language.TypeName;
import graphql.schema.GraphQLSchema;
import graphql.schema.idl.RuntimeWiring;
import graphql.schema.idl.SchemaGenerator;
Expand All @@ -12,7 +14,6 @@

import java.io.File;
import java.io.Reader;
import java.util.Comparator;

public final class Federation {
private static final SchemaGenerator.Options generatorOptions = SchemaGenerator.Options.defaultOptions();
Expand All @@ -22,17 +23,28 @@ private Federation() {

@NotNull
public static SchemaTransformer transform(final GraphQLSchema schema) {
return new SchemaTransformer(schema);
return new SchemaTransformer(schema, false);
}

// Note that GraphQLSchema does not support empty object types as of graphql-java v16. If you
// would like the query type to be empty, then add a dummy field to the query type in the given
// GraphQLSchema and pass queryTypeShouldBeEmpty as true. You can also use a transform()
// overload that accepts something other than a GraphQLSchema, as those overloads will
// automatically handle this for you. The output schema won't contain the dummy field, nor will
// it be visible to the gateway.
@NotNull
public static SchemaTransformer transform(final GraphQLSchema schema, final boolean queryTypeShouldBeEmpty) {
return new SchemaTransformer(schema, queryTypeShouldBeEmpty);
}

public static SchemaTransformer transform(final TypeDefinitionRegistry typeRegistry, final RuntimeWiring runtimeWiring) {
ensureQueryTypeExists(typeRegistry);
final boolean queryTypeShouldBeEmpty = ensureQueryTypeExists(typeRegistry);
RuntimeWiring newRuntimeWiring = ensureFederationDirectiveDefinitionsExist(typeRegistry, runtimeWiring);
final GraphQLSchema original = new SchemaGenerator().makeExecutableSchema(
generatorOptions,
typeRegistry,
newRuntimeWiring);
return transform(original);
return transform(original, queryTypeShouldBeEmpty);
}

public static SchemaTransformer transform(final TypeDefinitionRegistry typeRegistry) {
Expand Down Expand Up @@ -67,17 +79,34 @@ private static RuntimeWiring emptyWiring() {
return RuntimeWiring.newRuntimeWiring().build();
}

private static void ensureQueryTypeExists(TypeDefinitionRegistry typeRegistry) {
// Returns true if a dummy field was added to the query type to ensure it's not empty.
private static boolean ensureQueryTypeExists(TypeDefinitionRegistry typeRegistry) {
final String queryName = typeRegistry.schemaDefinition()
.flatMap(sdef -> sdef.getOperationTypeDefinitions()
.stream()
.filter(op -> "query".equals(op.getName()))
.findFirst()
.map(def -> def.getTypeName().getName()))
.orElse("Query");
if (!typeRegistry.getType(queryName).isPresent()) {
typeRegistry.add(ObjectTypeDefinition.newObjectTypeDefinition().name(queryName).build());
TypeDefinition<?> newQueryType = typeRegistry
.getType(queryName)
.orElse(ObjectTypeDefinition.newObjectTypeDefinition().name(queryName).build());
final boolean addDummyField = newQueryType instanceof ObjectTypeDefinition
&& ((ObjectTypeDefinition) newQueryType).getFieldDefinitions().isEmpty();
if (addDummyField) {
newQueryType = ((ObjectTypeDefinition) newQueryType).transform(objectTypeDefinitionBuilder ->
objectTypeDefinitionBuilder.fieldDefinition(FieldDefinition.newFieldDefinition()
.name("_dummy")
.type(new TypeName("String"))
.build()
)
);
}
// Note that TypeDefinitionRegistry will throw if you attempt to redefine a type, but it
// reacts fine if you try to remove a type that doesn't exist.
typeRegistry.remove(newQueryType);
typeRegistry.add(newQueryType);
return addDummyField;
}

private static RuntimeWiring ensureFederationDirectiveDefinitionsExist(
Expand Down
Loading

0 comments on commit e612aa8

Please sign in to comment.