/** * This helps you transform the current GraphQLFieldDefinition 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 field based on calling build on that builder */ public GraphQLFieldDefinition transform(Consumer<Builder> builderConsumer) { Builder builder = newFieldDefinition(this); builderConsumer.accept(builder); return builder.build(); }
@SuppressWarnings("unchecked") public Builder(GraphQLFieldDefinition existing) { this.name = existing.getName(); this.description = existing.getDescription(); this.type = existing.getType(); this.dataFetcherFactory = DataFetcherFactories.useDataFetcher(existing.getDataFetcher()); this.deprecationReason = existing.getDeprecationReason(); this.definition = existing.getDefinition(); this.arguments.putAll(getByName(existing.getArguments(), GraphQLArgument::getName)); this.directives.putAll(getByName(existing.getDirectives(), GraphQLDirective::getName)); }
private static Object fakeObjectValue(GraphQLObjectType fieldType) { Map<String, Object> map = new LinkedHashMap<>(); fieldType.getFieldDefinitions().forEach(fldDef -> { GraphQLOutputType innerFieldType = fldDef.getType(); Object obj = null; if (innerFieldType instanceof GraphQLObjectType) { obj = fakeObjectValue((GraphQLObjectType) innerFieldType); } else if (innerFieldType instanceof GraphQLScalarType) { obj = fakeScalarValue(fldDef.getName(), (GraphQLScalarType) innerFieldType); } map.put(fldDef.getName(), obj); }); return map; }
private TypePrinter<GraphQLInterfaceType> interfacePrinter() { return (out, type, visibility) -> { if (isIntrospectionType(type)) { return; } printComments(out, type, ""); out.format("interface %s%s {\n", type.getName(), directivesString(type.getDirectives())); visibility.getFieldDefinitions(type) .stream() .sorted(Comparator.comparing(GraphQLFieldDefinition::getName)) .forEach(fd -> { printComments(out, fd, " "); out.format(" %s%s: %s%s\n", fd.getName(), argsString(fd.getArguments()), typeString(fd.getType()), directivesString(fd.getDirectives())); }); out.format("}\n\n"); }; }
public static GraphQLQuery query(GraphQLFieldDefinition definition){ final String id = generateId(); final GraphQLQuery query = new GraphQLQuery(); query.setId(id); query.setName(definition.getName()); query.setDescription(definition.getDescription()); query.setResponseStrategy(GraphQLResponseStrategy.RANDOM); query.setStatus(GraphQLOperationStatus.MOCKED); for(graphql.schema.GraphQLArgument argument : definition.getArguments()){ GraphQLArgument graphQLArgument = getArgument(argument); query.getArguments().add(graphQLArgument); } GraphQLResult result = getResult(definition.getType()); query.setResult(result); return query; }
if (mutation.getType() instanceof GraphQLObjectType) { outputFields = ((GraphQLObjectType) mutation.getType()).getFieldDefinitions(); } else { outputFields = new ArrayList<>(); outputFields.add(GraphQLFieldDefinition.newFieldDefinition() .name(relayMappingConfig.wrapperFieldName) .description(relayMappingConfig.wrapperFieldDescription) .type(mutation.getType()) .dataFetcher(DataFetchingEnvironment::getSource) .build()); List<GraphQLInputObjectField> inputFields = mutation.getArguments().stream() .map(arg -> GraphQLInputObjectField.newInputObjectField() .name(arg.getName()) .collect(Collectors.toList()); GraphQLInputObjectType inputObjectType = newInputObject() .name(mutation.getName() + "Input") .field(newInputObjectField() .name(CLIENT_MUTATION_ID) .build(); GraphQLObjectType outputType = newObject() .name(mutation.getName() + "Payload") .field(newFieldDefinition() .name(CLIENT_MUTATION_ID) .type(new GraphQLNonNull(GraphQLString)) return newFieldDefinition()
private void traverseFields(MergedField fieldList, GraphQLFieldsContainer parentFieldType, String fieldPrefix) { FieldCollectorParameters parameters = FieldCollectorParameters.newParameters() .schema(graphQLSchema) .objectType(asObjectTypeOrNull(parentFieldType)) .fragments(fragmentsByName) .variables(variables) .build(); MergedSelectionSet collectedFields = fieldCollector.collectFields(parameters, fieldList); for (Map.Entry<String, MergedField> entry : collectedFields.getSubFields().entrySet()) { String fieldName = mkFieldName(fieldPrefix, entry.getKey()); MergedField collectedFieldList = entry.getValue(); selectionSetFields.put(fieldName, collectedFieldList); Field field = collectedFieldList.getSingleField(); GraphQLFieldDefinition fieldDef = Introspection.getFieldDef(graphQLSchema, parentFieldType, field.getName()); GraphQLType unwrappedType = GraphQLTypeUtil.unwrapAll(fieldDef.getType()); Map<String, Object> argumentValues = valuesResolver.getArgumentValues(fieldDef.getArguments(), field.getArguments(), variables); selectionSetFieldArgs.put(fieldName, argumentValues); selectionSetFieldDefinitions.put(fieldName, fieldDef); flattenedFields.add(fieldName); if (unwrappedType instanceof GraphQLFieldsContainer) { traverseFields(collectedFieldList, (GraphQLFieldsContainer) unwrappedType, fieldName); } } }
@Test public void noArgMutation() { GraphQLObjectType object = GraphQLAnnotations.object(TestObject.class); GraphQLFieldDefinition doSomething = object.getFieldDefinition("doSomething"); assertNotNull(doSomething); assertEquals(doSomething.getArguments().size(), 1); GraphQLInputType input = doSomething.getArgument("input").getType(); assertTrue(input instanceof GraphQLNonNull); GraphQLType inputType = ((graphql.schema.GraphQLNonNull) input).getWrappedType(); assertTrue(inputType instanceof GraphQLInputObjectType); assertTrue(doSomething.getType() instanceof GraphQLObjectType); GraphQLObjectType returnType = (GraphQLObjectType) doSomething.getType(); assertNotNull(returnType.getFieldDefinition("getI")); assertNotNull(returnType.getFieldDefinition("clientMutationId")); GraphQLSchema schema = GraphQLSchema.newSchema().query(object).mutation(object).build(); GraphQL graphQL = GraphQL.newGraphQL(schema).queryExecutionStrategy(new EnhancedExecutionStrategy()).build(); ExecutionResult result = graphQL.execute("mutation { doSomething(input: {clientMutationId: \"1\"}) { getI clientMutationId } }", new TestObject()); assertEquals(result.getErrors().size(), 0); Map<String, Object> returns = (Map<String, Object>) ((Map<String, Object>) result.getData()).get("doSomething"); assertEquals(returns.get("getI"), 0); assertEquals(returns.get("clientMutationId"), "1"); }
private void buildDefinitionMap(List<GraphQLFieldDefinition> fieldDefinitions) { for (GraphQLFieldDefinition fieldDefinition : fieldDefinitions) { String name = fieldDefinition.getName(); if (fieldDefinitionsByName.containsKey(name)) throw new AssertException(format("Duplicated definition for field '%s' in interface '%s'", name, this.name)); fieldDefinitionsByName.put(name, fieldDefinition); } }
@Override public GraphQLInputObjectType getInputObject(GraphQLObjectType graphQLType, String newNamePrefix) { GraphQLObjectType object = graphQLType; return new GraphQLInputObjectType("" + newNamePrefix + object.getName(), object.getDescription(), object.getFieldDefinitions().stream(). map(field -> { GraphQLOutputType type = field.getType(); GraphQLInputType inputType; if (type instanceof GraphQLObjectType) { inputType = getInputObject((GraphQLObjectType) type, newNamePrefix); } else { inputType = (GraphQLInputType) type; } return new GraphQLInputObjectField(field.getName(), field.getDescription(), inputType, null); }). collect(Collectors.toList())); }
private FieldDefAndDirectiveParams buildField(BuildContext buildCtx, TypeDefinition parentType, FieldDefinition fieldDef) { buildCtx.enterNode(fieldDef); GraphQLFieldDefinition.Builder builder = GraphQLFieldDefinition.newFieldDefinition(); builder.definition(fieldDef); builder.name(fieldDef.getName()); builder.description(schemaGeneratorHelper.buildDescription(fieldDef, fieldDef.getDescription())); builder.deprecate(schemaGeneratorHelper.buildDeprecationReason(fieldDef.getDirectives())); GraphQLDirective[] directives = buildDirectives(fieldDef.getDirectives(), Collections.emptyList(), DirectiveLocation.FIELD_DEFINITION, buildCtx.getDirectiveDefinitions()); builder.withDirectives( directives ); fieldDef.getInputValueDefinitions().forEach(inputValueDefinition -> builder.argument(buildArgument(buildCtx, inputValueDefinition))); GraphQLOutputType fieldType = buildOutputType(buildCtx, fieldDef.getType()); builder.type(fieldType); GraphQLFieldDefinition fieldDefinition = builder.build(); // if they have already wired in a fetcher - then leave it alone FieldCoordinates coordinates = FieldCoordinates.coordinates(parentType.getName(), fieldDefinition.getName()); if (!buildCtx.codeRegistry.hasDataFetcher(coordinates)) { DataFetcherFactory dataFetcherFactory = buildDataFetcherFactory(buildCtx, parentType, fieldDef, fieldType, Arrays.asList(directives)); buildCtx.getCodeRegistry().dataFetcher(coordinates, dataFetcherFactory); } return buildCtx.exitNode(new FieldDefAndDirectiveParams(fieldDefinition, buildCtx.mkBehaviourParams())); }
@Override public DataFetcher build() { GraphQLDataFetcher dataFetcher = method.getAnnotation(GraphQLDataFetcher.class); DataFetcher actualDataFetcher; if (dataFetcher == null && method.getAnnotation(GraphQLBatched.class) != null) { actualDataFetcher = new BatchedMethodDataFetcher(method, typeFunction, container); } else if (dataFetcher == null) { actualDataFetcher = new MethodDataFetcher(method, typeFunction, container); } else { actualDataFetcher = dataFetcherConstructor.constructDataFetcher(method.getName(), dataFetcher); } if (method.isAnnotationPresent(GraphQLRelayMutation.class) && relayFieldDefinition != null) { actualDataFetcher = new RelayMutationMethodDataFetcher(method, args, relayFieldDefinition.getArgument("input").getType(), relayFieldDefinition.getType()); } if (isConnection){ actualDataFetcher = getConnectionDataFetcher(method.getAnnotation(GraphQLConnection.class), actualDataFetcher); } return actualDataFetcher; } }
@Override public TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext<GraphQLType> context) { GraphQLFieldsContainer parentContainerType = (GraphQLFieldsContainer) context.getParentContext().thisNode(); DataFetcher dataFetcher = node.getDataFetcher(); if (dataFetcher == null) { dataFetcher = new PropertyDataFetcher<>(node.getName()); } FieldCoordinates coordinates = coordinates(parentContainerType, node); codeRegistry.dataFetcherIfAbsent(coordinates, dataFetcher); return CONTINUE; }
private void checkFieldArgumentEquivalence(GraphQLObjectType objectTyoe, GraphQLInterfaceType interfaceType, SchemaValidationErrorCollector validationErrorCollector, GraphQLFieldDefinition interfaceFieldDef, GraphQLFieldDefinition objectFieldDef) { List<GraphQLArgument> interfaceArgs = interfaceFieldDef.getArguments(); List<GraphQLArgument> objectArgs = objectFieldDef.getArguments(); if (interfaceArgs.size() != objectArgs.size()) { validationErrorCollector.addError( error(format("object type '%s' does not implement interface '%s' because field '%s' has a different number of arguments", objectTyoe.getName(), interfaceType.getName(), interfaceFieldDef.getName()))); } else { for (int i = 0; i < interfaceArgs.size(); i++) { GraphQLArgument interfaceArg = interfaceArgs.get(i); GraphQLArgument objectArg = objectArgs.get(i); String interfaceArgStr = makeArgStr(interfaceArg); String objectArgStr = makeArgStr(objectArg); boolean same = true; if (!interfaceArgStr.equals(objectArgStr)) { same = false; } if (!Objects.equals(interfaceArg.getDefaultValue(), objectArg.getDefaultValue())) { same = false; } if (!same) { validationErrorCollector.addError( error(format("object type '%s' does not implement interface '%s' because field '%s' argument '%s' is defined differently", objectTyoe.getName(), interfaceType.getName(), interfaceFieldDef.getName(), interfaceArg.getName()))); } } } }
private void traverse(GraphQLOutputType root, List<SchemaValidationRule> rules, SchemaValidationErrorCollector validationErrorCollector) { if (processed.contains(root)) { return; } processed.add(root); if (root instanceof GraphQLFieldsContainer) { // this deliberately has open field visibility here since its validating the schema // when completely open for (GraphQLFieldDefinition fieldDefinition : ((GraphQLFieldsContainer) root).getFieldDefinitions()) { for (SchemaValidationRule rule : rules) { rule.check(fieldDefinition, validationErrorCollector); } traverse(fieldDefinition.getType(), rules, validationErrorCollector); } } } }
@Test public void testQueryArguments() { GraphQLSchema schema = GraphQLSchemaBuilder.newBuilder().registerGraphQLControllerObjects(ImmutableList.<Object> of(new TestController())).build(); GraphQLFieldDefinition queryType = schema.getQueryType().getFieldDefinition("testQueryArguments"); assertEquals("testQueryArguments", queryType.getName()); assertEquals(Scalars.GraphQLString, queryType.getArgument("string").getType()); assertEquals(Scalars.GraphQLInt, queryType.getArgument("int").getType()); assertEquals(GraphQLInputObjectType.class, queryType.getArgument("test").getType().getClass()); assertEquals("RenamedTestInputType_Input", queryType.getArgument("test").getType().getName()); }
@SuppressWarnings("serial") @Test public void testMethodBasedFields() { IGraphQLObjectMapper graphQLObjectMapper = newGraphQLObjectMapper( ImmutableList.<IGraphQLTypeMapper> builder().add(new TestTypeMapper()).addAll(GraphQLSchemaBuilder.getDefaultTypeMappers()).build()); GraphQLObjectType objectType = (GraphQLObjectType) graphQLObjectMapper.getOutputType(new TypeToken<MethodBasedFields>() { }.getType()); assertEquals(MethodBasedFields.class.getSimpleName(), objectType.getName()); assertEquals(2, objectType.getFieldDefinitions().size()); assertNotNull(objectType.getFieldDefinition("stringField")); assertEquals(Scalars.GraphQLString, objectType.getFieldDefinition("stringField").getType()); assertNotNull(objectType.getFieldDefinition("stringList")); assertEquals(GraphQLList.class, objectType.getFieldDefinition("stringList").getType().getClass()); assertEquals(Scalars.GraphQLString, ((GraphQLList) objectType.getFieldDefinition("stringList").getType()).getWrappedType()); assertNull(objectType.getFieldDefinition("ignoredObject")); assertEquals(DefaultMethodDataFetcher.class, objectType.getFieldDefinition("stringField").getDataFetcher().getClass()); assertEquals(CollectionConverterDataFetcher.class, objectType.getFieldDefinition("stringList").getDataFetcher().getClass()); }
@Override public void check(GraphQLFieldDefinition fieldDef, SchemaValidationErrorCollector validationErrorCollector) { for (GraphQLArgument argument : fieldDef.getArguments()) { GraphQLInputType argumentType = argument.getType(); if (argumentType instanceof GraphQLInputObjectType) { List<String> path = new ArrayList<>(); path.add(argumentType.getName()); check((GraphQLInputObjectType) argumentType, new LinkedHashSet<>(), path, validationErrorCollector); } } }
@Override public GraphQLFieldDefinition onField(SchemaDirectiveWiringEnvironment<GraphQLFieldDefinition> environment) { GraphQLFieldDefinition field = environment.getElement(); String fetchName = atFetchFromSupport(field.getName(), field.getDirectives()); DataFetcher dataFetcher = new PropertyDataFetcher(fetchName); environment.getCodeRegistry().dataFetcher(coordinates(environment.getFieldsContainer(), field), dataFetcher); return field; }
@SuppressWarnings("unchecked") @Test public void testDocumentedControllerAndMethods() { GraphQLSchema schema = GraphQLSchemaBuilder.newBuilder() .registerTypeFactory(new JacksonTypeFactory(new ObjectMapper())) .registerGraphQLControllerObjects(ImmutableList.<Object>of(new DocumentedMethodsTest())) .build(); GraphQLObjectType mutationType = (GraphQLObjectType) schema.getMutationType().getFieldDefinition("Mutations").getType(); GraphQLObjectType queryType = (GraphQLObjectType) schema.getQueryType().getFieldDefinition("Queries").getType();; assertEquals("Mutation Description", mutationType.getDescription()); assertEquals("Query Description", queryType.getDescription()); GraphQLFieldDefinition someQuery = queryType.getFieldDefinition("getSomeStrings"); GraphQLFieldDefinition someMutation = mutationType.getFieldDefinition("setSomeStrings"); assertEquals("getSomeStrings description", someQuery.getDescription()); assertEquals("setSomeStrings description", someMutation.getDescription()); } }