Getting started with GraphQL (Java)

GraphQL is query language for your Rest APIs and gives client power to select exactly what they need. It also provides server side runtime to execute the queries.

GraphQL has 3 major parts

  1. GraphQL server
  2. GraphQL Schema
  3. Client

GraphQL Server

GraphQL server is responsible to validate & execute the queries and returns the response as per client’s need. The client can select the fields as per need and server will return only those selected fields.

GraphQL Schema

GraphQL has a specific language called GraphQL Schema language to define schema. GraphQL schema consist of the queries and types. As a API owner we can decide what queries & types will be available to the consumer. The schema has default root object type called Query which contains all the queries. An example schema is

#The root object
type Query {
    hello: String
    greet(name: String): String
}
 #Defined Type
type User{
    name: String
    age: Int
}

In above schema root object is Query and it has one field called hello and a method greet and both are returning String type. The greet has an input argument name which is a type of String. This means client can pass any string type argument while querying greet.

The User type is defined type which has 2 fields name and age. GraphQL supports several built-in types like String, Int, Float, Boolean, etc. Click here to read more about graphql schema and types.

For every field or query in the Query Type will have corresponding resolver which will be running at GraphQL Server.

Client

The clients are the consumer. Since GraphQL works over Rest so any rest client can query the graphql. There are few tools which are great for testing. These tools gives the auto-completion features and we can view all possible queries and types. Some of the tools are GraphiQL, insomnia.

GraphQL-Java in Action

Below code will demonstrate you how to integrate GraphQL in Spring application. So let’s start with the GraphQL schema file.

The code structure will look like

GraphQL code structure

Define schema file users.graphql
type Query {
    hello: String
    users(name: String): User
}

type User {
    name: String
    age: Int
    address: String
}

Now well start configuring the GraphQL Java objects along with resolvers for the queries (hello & user).

Step 1: Read & parse schema file

Filename: GraphQLSchema.java

    private TypeDefinitionRegistry readAndParseSchemaFile() throws Exception {
        String schemaString = ResourceUtils.readClasspathResourceContent("users.graphql");

        SchemaParser schemaParser = new SchemaParser();
        
        // parsing schema file and creating typeDefRegistery
        return schemaParser.parse(schemaString);
    }
Step 2: Configure Resolvers
    private RuntimeWiring buildRuntimeWiring() {
        return RuntimeWiring.newRuntimeWiring()
                .type("Query", builder -> builder.dataFetchers(buildDataFetchers()))
                .build();
    }

    private Map<String, DataFetcher> buildDataFetchers() {
        Map<String, DataFetcher> dataFetchers = new HashMap<>();
        dataFetchers.put("hello", new StaticDataFetcher("Welcome to GraphQL world."));
        dataFetchers.put("users", env -> User.of("John", 28, "India"));
        return dataFetchers;
    }
Step 3: Prepare GraphQL object and execute query
    private void setup() throws Exception {
        // We need to create GraphQLSchema Object but before that we need to configure resolvers 
        GraphQLSchema graphQLSchema = new SchemaGenerator().makeExecutableSchema(readAndParseSchemaFile(), buildRuntimeWiring());
        graphQL = GraphQL.newGraphQL(graphQLSchema).build();
    }
    
    public ExecutionResult executeQuery(String graphQLQuery) {
        return graphQL.execute(graphQLQuery);
    }
Step 4: Serve user queries on the endpoint (/graphql)
    @RestController
    public class GraphQLController {
    
        private final GraphQLService graphQLService;
    
        @Autowired
        public GraphQLController(GraphQLService graphQLService) {
            this.graphQLService = graphQLService;
        }
    
        @PostMapping("/graphql")
        public Map<String, Object> executeQuery(@RequestBody GraphQLRequest request) {
            return graphQLService.executeQuery(request.getQuery()).toSpecification();
        }
    }
Step 5: User GraphiQL or Rest to execute graphql query

GraphiQL resource links

Add your /graphql controller’s endpoint in GraphiQL and start executing query

Query hello

We can ask the response fields and graphql will serve only selected fields.

  1. Query users for name only

Name only

  1. Query users for all fields

All fields

We can ask for multiple queries in single request

Multiple queries

Even same query with multiple times with alias

Duplicate queries

You can find complete code here

Happy Coding 😀😀😀 !!!