GraphQL with spring-boot-starter-graphql

Sumitra Dhakre
Dev Genius
Published in
5 min readMay 30, 2022

--

Finally, after 10 months of waiting GraphQL is integrated with the latest release of spring boot 2.7.0. With this release, spring-boot-starter-graphql replaces the current GraphQL java spring. For more details on this release check here.

In this article, we’ll see how you can start using this new graphql starter or simply migrate your existing project. Here, I am using my previous project that was built with graphql java spring.

Requirements

Setup you’ll need:

  • Basic understanding of spring boot and GraphQL
  • Existing graphql java project or clone one here
  • Docker installed on your machine
  • Intellij or IDE of your choice
  • Postman for testing the API

Project Migration

Unlike before, with spring boot 2.7.0 we only need one dependency to integrate GraphQL in our project. So I started by upgrading the spring boot version to

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
<relativePath/>

Then I removed the previous graphql dependencies graphql-java-tools and graphql-spring-boot-starter.

<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-java-tools</artifactId>
<version>12.0.0</version>
</dependency>
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>12.0.0</version>
</dependency>

And added the new spring boot graphql starter

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-graphql</artifactId>
</dependency>

After this, remove all the implemented Resolvers and clean the project by removing all the imports from graphql java spring.

Now our project is clean and updated with the new dependencies. According to the spring graphql documentation, the biggest changes come with the new annotated controllers. The default location for schema files are src/main/resources/graphql/**. This is the case here, so we don’t need to touch the graphql schema files. All files will be picked up automatically by spring graphql starter.

schema file location

You can also customize the schema file location in the application.properties. But here we’ll go with the defaults.

GraphQL Annotations

With Graphql spring java the resolvers component is needed to implement GraphQLQueryResolver or GraphQLMutationResolver classes. But with the spring boot starter graphql, it’s moved to an annotation-based programming model. In short previous resolvers are replaced by annotations:

GraphQLMutationResolver -> @MutationMappingGraphQLQueryResolver -> @QueryMapping

And the @Controller component uses the annotated handler methods to bind and resolve graphql schema fields/queries.

Query Mapping

As the name suggests this annotation maps the handler method to the query type in graphql schema.

Query schema
BookQuery class with annotated query methods

Now let’s configure our query methods by annotating them with @QueryMapping. For mapping query argument we can use the annotation @Argument. For more flexibility you can also define alias names for the arguments for example

The query getBookByName has an argument filter in the schema and in the handler method, it’s bookFilter. So we need to define an alias with the @Argument(“filter”). If you forget to do this, your project will just deploy successfully but the query will end up with NPE. Which I wasted some time on, and later figured out it was just missing the right matching argument names.

Schema Mapping

This annotation maps and binds a handler with the field in the GraphQL schema, it can be used at the method or class level. It accepts two parameters typeName= and field=. It’s also the parent annotations of the other query-specific annotations.

schema mapping meta-annotations

We’ll need this annotation to resolve the author field type of the Book type.

book type in the schema
author resolver method with schema mapping annotation

Here we define the @SchemaMapping annotation with parameters

  • typeName= Book, which is the type to which the author field belongs
  • field= author, to specify which field of the specified typeName will be resolved by this handler method.

After, I defined the argument on the field, order with the @Argument annotation. As it has the same name order both in schema and handler method spring will map it automatically. Since we are defining the schema annotation at the method level the previous BookAuthorResolver class is unnecessary so I removed it and moved the method to the BookQuery class.

BookQuery class with query handler and author resolver methods

Mutation Mapping

This annotation maps handler methods with the mutation query in the GraphQL schema.

mutation schema
deleteBook method with mutation annotation

Just like we changed for the queryMapping, add the @MutationMapping to the mutation query method and annotate the mutation argument with @Argument(“input”) annotation with the alias.

Since Mutation and Query mapping annotations are meta-annotations of SchemaMapping, we can also replace them like this.

defining mutation method with @SchemaMapping annotation

TEST API

Now all the changes are done let's build and run the project.

mvn clean install

Then deploy with docker.

docker-compose up -d

docker containers

Let’s test one query first

allBook query in postman

As mentioned in the specs, the new spring graphql starter uses Runtime wiring to register handler methods to the graphql.schema.Datafetcher. Therefore even if you annotate a handler method wrong like, instead of @QueryMapping you accidentally put @MutationMapping

You won’t see any errors but the result won’t be the one expected. So just be careful while annotating the handler methods.

Now let’s test one mutation.

newBook mutation in postman

The API works as expected. I hope this quick article will help you get started with the new spring-boot-graphql-starter and play with the other cool features it has. You can check out this project on github here. If you like this article be sure to check out my other articles related to spring boot.

--

--