Why is DataFetcher not called in this GraphQL setup?

3.7k views Asked by At

I want to write a piece of code, which will handle GraphQL queries like these:

  query {
      group(id: "com.graphql-java")
      name(name: "graphql-java")
      version(id: "2.3.0")
  }

I've created a data fetcher and put a breakpoint inside the get method:

  import graphql.schema.DataFetcher;
  import graphql.schema.DataFetchingEnvironment;

  public class TestDataFetcher implements DataFetcher {
      public Object get(final DataFetchingEnvironment dataFetchingEnvironment) {
          return null;
      }
  }

Then I wrote the following code:

  public class Example02 {
      public static void main(final String[] args) throws IOException {
          final Example02 app = new Example02();
          app.run();
      }
      void run() throws IOException {
          final TestDataFetcher testDataFetcher = new TestDataFetcher();

          final List<GraphQLFieldDefinition> fields = Lists.newArrayList(
                  createGroupField(testDataFetcher),
                  createNameField(),
                  createVersionField());

          final GraphQLObjectType queryType = newObject()
                  .name("query")
                  .fields(fields)
                  .build();
          final GraphQLSchema schema = GraphQLSchema.newSchema()
                  .query(queryType)
                  .build();
          final String query = FileUtils.readFileToString(
                  new File("src/main/resources/query1.txt"),
                  "UTF-8"
          );
          final Map<String, Object> result = (Map<String, Object>) new GraphQL(schema).execute(query).getData();
          System.out.println(result);
      }

      private GraphQLFieldDefinition createVersionField() {
          return newFieldDefinition().type(GraphQLString).name("version").build();
      }

      private GraphQLFieldDefinition createNameField() {
          return newFieldDefinition().type(GraphQLString).name("name").build();
      }

      private GraphQLFieldDefinition createGroupField(TestDataFetcher testDataFetcher) {
          final GraphQLArgument idArg = newArgument().name("id").type(GraphQLString).build();
          return newFieldDefinition()
                  .type(GraphQLString)
                  .name("group")
                  .dataFetcher(testDataFetcher)
                  .argument(idArg)
                  .build();
      }
  }

When I run the main method in debug mode, the breakpoint is not activated.

Why? How can I fix it?

2

There are 2 answers

0
Sergey Benner On BEST ANSWER

Here's your working sample. i've used your query file as you posted it. Implement your dataFetcher as needed further. Basically you should've defined the arguments for the name and version fields. The debugger tells everything when you run new GraphQL(schema).execute(query) it has errors array which contains all the problems.

import graphql.GraphQL;
import graphql.schema.*;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static graphql.Scalars.GraphQLString;
import static graphql.schema.GraphQLArgument.newArgument;
import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition;
import static graphql.schema.GraphQLObjectType.newObject;

public class Example2 {


    public class TestDataFetcher implements DataFetcher {
        public Object get(DataFetchingEnvironment environment) {
            String id = (String)environment.getArgument("id");
            return id;
        }
    }

    public static void main(final String[] args)  {
        Example2 app = new Example2();
        app.run();
    }
    void run() {
         TestDataFetcher testDataFetcher = new TestDataFetcher();   

         List<GraphQLFieldDefinition> fields = new ArrayList<GraphQLFieldDefinition>();

            fields.add(createGroupField(testDataFetcher));
                fields.add(createNameField());
                fields.add(createVersionField());

         GraphQLObjectType queryType = newObject()
                .name("query")
                .fields(fields)
                .build();

         GraphQLSchema schema = GraphQLSchema.newSchema()
                .query(queryType)
                .build();
        String query = null;
        try {
              query = FileUtils.readFileToString(
                    new File("src/main/resources/query1.txt"),
                    "UTF-8"
            );
        }catch(IOException ioe){
            ioe.printStackTrace();
        }

        if(query!=null) {
            Map<String, Object> result = (Map<String, Object>) new GraphQL(schema).execute(query).getData();
            System.out.println(result);
        }
    }

    private GraphQLFieldDefinition createVersionField() {
         GraphQLArgument arg = newArgument().name("id").type(GraphQLString).build();
        return newFieldDefinition().type(GraphQLString).name("version").argument(arg).build();
    }

    private GraphQLFieldDefinition createNameField() {
        GraphQLArgument arg = newArgument().name("name").type(GraphQLString).build();
        return newFieldDefinition().type(GraphQLString).name("name").argument(arg).build();
    }

    private GraphQLFieldDefinition createGroupField(TestDataFetcher testDataFetcher) {
        final GraphQLArgument idArg = newArgument().name("id").type(GraphQLString).build();
        return newFieldDefinition()
                .type(GraphQLString)
                .name("group")
                .dataFetcher(testDataFetcher)
                .argument(idArg)
                .build();
    }
}
1
Kordon On

Your problem is your query. If you debug the variable query it is query {\n group(id: "com.graphql-java")\n name(name: "graphql-java")\n version(id: "2.3.0")\n}. The problem is the '\n' in the query.

If you change your query to query{group(id: "com.graphql-java")} your breakpoint will be executed.

To execute your query I had to update the GraphQlFiledDefinitions first to receive the argument.

private GraphQLFieldDefinition createVersionField(TestDataFetcher testDataFetcher) {
    final GraphQLArgument idArg = newArgument().name("id").type(GraphQLString).build();
    return newFieldDefinition().type(GraphQLString).name("version").staticValue("id value").argument(idArg).build();
}

private GraphQLFieldDefinition createNameField(TestDataFetcher testDataFetcher) {
    final GraphQLArgument nameArg = newArgument().name("name").type(GraphQLString).build();
    return newFieldDefinition().type(GraphQLString).name("name").staticValue("name Value").argument(nameArg).build();
}

private GraphQLFieldDefinition createGroupField(TestDataFetcher testDataFetcher) {
    final GraphQLArgument idArg = newArgument().name("id").type(GraphQLString).build();
    return newFieldDefinition()
            .type(GraphQLString)
            .name("group")
            .dataFetcher(testDataFetcher)
            .argument(idArg)
            .build();
}

And then I can use the query without line breaks query {group(id: "com.graphql-java"),name(name:"graphql-java"),version(id: "2.3.0")}