com.apollographql.federation.graphqljava.SchemaTransformer Maven / Gradle / Ivy
package com.apollographql.federation.graphqljava;
import static com.apollographql.federation.graphqljava.printer.ServiceSDLPrinter.generateServiceSDL;
import static com.apollographql.federation.graphqljava.printer.ServiceSDLPrinter.generateServiceSDLV2;
import com.apollographql.federation.graphqljava.exceptions.MissingKeyException;
import graphql.GraphQLError;
import graphql.language.BooleanValue;
import graphql.language.StringValue;
import graphql.schema.Coercing;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetcherFactory;
import graphql.schema.FieldCoordinates;
import graphql.schema.GraphQLAppliedDirectiveArgument;
import graphql.schema.GraphQLArgument;
import graphql.schema.GraphQLCodeRegistry;
import graphql.schema.GraphQLDirectiveContainer;
import graphql.schema.GraphQLInterfaceType;
import graphql.schema.GraphQLNamedType;
import graphql.schema.GraphQLObjectType;
import graphql.schema.GraphQLSchema;
import graphql.schema.GraphQLType;
import graphql.schema.TypeResolver;
import graphql.schema.idl.errors.SchemaProblem;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.jetbrains.annotations.NotNull;
public final class SchemaTransformer {
private static final Object serviceObject = new Object();
private final GraphQLSchema originalSchema;
private final boolean queryTypeShouldBeEmpty;
private TypeResolver entityTypeResolver = null;
private DataFetcher entitiesDataFetcher = null;
private DataFetcherFactory entitiesDataFetcherFactory = null;
private Coercing coercingForAny = _Any.type.getCoercing();
private boolean isFederation2 = false;
SchemaTransformer(GraphQLSchema originalSchema, boolean queryTypeShouldBeEmpty) {
this.originalSchema = originalSchema;
this.queryTypeShouldBeEmpty = queryTypeShouldBeEmpty;
}
@NotNull
public SchemaTransformer resolveEntityType(TypeResolver entityTypeResolver) {
this.entityTypeResolver = entityTypeResolver;
return this;
}
@NotNull
public SchemaTransformer fetchEntities(DataFetcher entitiesDataFetcher) {
this.entitiesDataFetcher = entitiesDataFetcher;
this.entitiesDataFetcherFactory = null;
return this;
}
@NotNull
public SchemaTransformer fetchEntitiesFactory(DataFetcherFactory entitiesDataFetcherFactory) {
this.entitiesDataFetcher = null;
this.entitiesDataFetcherFactory = entitiesDataFetcherFactory;
return this;
}
public SchemaTransformer coercingForAny(Coercing coercing) {
this.coercingForAny = coercing;
return this;
}
public SchemaTransformer setFederation2(boolean isFederation2) {
this.isFederation2 = isFederation2;
return this;
}
@NotNull
public GraphQLSchema build() throws SchemaProblem {
// Make new Schema
final GraphQLSchema.Builder newSchema = GraphQLSchema.newSchema(originalSchema);
final GraphQLObjectType originalQueryType = originalSchema.getQueryType();
final GraphQLObjectType.Builder newQueryType = GraphQLObjectType.newObject(originalQueryType);
if (queryTypeShouldBeEmpty) newQueryType.clearFields();
newQueryType.field(_Service.field);
final Set entityTypeNames = getFederatedEntities();
// If there are entity types install: Query._entities(representations: [_Any!]!): [_Entity]!
if (!entityTypeNames.isEmpty()) {
newQueryType.field(_Entity.field(entityTypeNames));
final GraphQLType originalAnyType = originalSchema.getType(_Any.typeName);
if (originalAnyType == null) {
newSchema.additionalType(_Any.type.transform((it) -> it.coercing(coercingForAny)));
}
}
newSchema.query(newQueryType.build());
final GraphQLCodeRegistry.Builder newCodeRegistry =
updateCodeRegistryWithEntityResolvers(entityTypeNames);
// expose the schema as _service.sdl
newCodeRegistry.dataFetcher(
FieldCoordinates.coordinates(originalQueryType.getName(), _Service.fieldName),
(DataFetcher