Spring Boot With GraphQL: What The Cool Kids Are Doing
Tags: springboot, graphql, java, rest
Published: 2021-07-07 22:33:04

This article is going to introduce you to Spring Boot with GraphQL. We’ll walk through a simple beer app to show you what it can do.

So you have built this really sweet API with all the <code>gets</code>, <code>puts</code>, and <code>deletes</code> you can think of. Your baby is just beautiful the way it is, right? Well, maybe developer Joe thinks your baby is fat.

WHAT?!

The RESTful calls you have are bringing back way too much information. In other scenarios, the calls don’t do enough, and your baby is left crying because it needs more to play with.

Well, this is where the power of GraphQL comes in.
<h2>Graph-What?</h2>
The new kid on the block in querying APIs is called GraphQL. Okay, but what is it? Well, the definition pulled directly from the <a href="https://graphql.org/">GraphQL</a> site is:
<p style="padding-left: 40px;">"GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools."</p>
Uh-huh. Great. But what is it?

GraphQL is a tool that allows you to get what you want and only what you want from your existing API. You can eliminate the things you don’t need or care about in implementation. It can also offer a one place, one call to join what would otherwise be multiple REST calls to get the same information. GraphQL can significantly speed up performance and simplify coding.

Here is a video introduction to <a href="https://keyholesoftware.com/company/creations/presentations/graphql-key-concepts/">GraphQL</a>, as well as some more information on why it's cool and what you can do with it.
<h2>Not In This Article</h2>
This article is not going to go into an in-depth explanation about Spring Boot (nor Spring Boot’s complete awesomeness). We will also avoid the arguments about development usage for and against it versus things like NodeJS or .NET.

That said, this article does assume that you are at least familiar with Spring Boot and Java already. It is more about how you can be a part of the “cool” crowd and implement GraphQL in your Java project.
<h2>Let’s Doll Up Your GraphQL Baby with Spring Boot</h2>
First things first, you must either have an existing API built into Spring Boot, or you can conveniently use the Beer App provided at the end of this article.

Next, you will need to add these into your pom if not already there.

<code>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- GraphQL -->
        <dependency>
            <groupId>com.graphql-java-kickstart</groupId>
            <artifactId>graphql-spring-boot-starter</artifactId>
            <version>7.0.1</version>
        </dependency>
        <!-- to embed GraphiQL tool -->
        <dependency>
            <groupId>com.graphql-java-kickstart</groupId>
            <artifactId>graphiql-spring-boot-starter</artifactId>
            <version>7.0.1</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
 
</code>

Next, in your <code>application.properties</code> file add the following:

<code>
graphql.servlet.mapping=/graphql
graphql.servlet.enabled=true
graphql.servlet.exception-handlers-enabled= true
graphql.servlet.contextSetting= PER_REQUEST_WITH_INSTRUMENTATION
# GraphiQL (not GraphQL!)
graphiql.mapping= /graphiql
graphiql.endpoint.graphql= /graphql
graphiql.static.basePath= /
graphiql.enabled= true
graphiql.pageTitle= GraphiQL
graphiql.props.resources.defaultQuery= schema.graphqls
graphiql.props.variables.editorTheme= "solarized light"
</code>

These settings tell GraphQL where everything is set up. GraphiQL is a graphical interface that you can use to test out your GraphQL queries.

This is an important feature that will help you get familiar with using GraphiQL (not a typo!). Keep in mind that if you are using an existing API, you will need to add exceptions to your security filtering rules or log in first Here is more information on how to use <a href="https://github.com/skevy/graphiql-app">GraphiQL</a>.

Next, let's look at the mutators and query classes. A <code>mutation</code> is something that will change data. So this is your creating, updating, or deleting of data. The query classes are just that: methods that query the database or “get” data.
<h4>EntityMutationResolver.java:</h4>

<code>
@Component
public class EntityMutationResolver implements GraphQLMutationResolver {
 
    private final BrewerService brewerService;
    private final BeerService beerService;
 
    /**
     * Constructor that takes instances of injected service bean for all entities
     * 
     * @param brewerService An instance of Spring managed BrewerService bean
     * @param beerService An instance of Spring managed BeerService bean
     */
    public EntityMutationResolver( BrewerService brewerService,
            BeerService beerService) {
        this.brewerService = brewerService;
        this.beerService = beerService;
    }
 
    /**
     * Adds a Brewer entity
     * 
     * @param name Name of the Brewer
     * @return An instance of Brewer if created successfully
     * @throws Exception If any occurred
     */
    public Brewer addBrewer(String name) throws Exception {
        Brewer brewer = new Brewer(name);
        return brewerService.save(brewer);
    }
</code>

The key here is that it implements <code>GraphQLMutationResolver</code>.

Here, we define the methods that are described in the GraphQL schema. We’ll get to that more later.
<h4>EntityQueryResolver.java:</h4>

<code>
@Component
public class EntityQueryResolver implements GraphQLQueryResolver {
 
    private final BrewerService brewerService;
    private final BeerService beerService;
 
    /**
     * Constructor that takes instances of injected service bean for all entities
     * 
     * @param brewerService An instance of Spring managed BrewerService bean
     * @param beerService An instance of Spring managed BeerService bean
     */
    public EntityQueryResolver(BrewerService brewerService,
        BeerService beerService) {
        this.brewerService = brewerService;
        this.beerService = beerService;
    }
 
    /**
     * Returns a Brewer for the given id
     * 
     * @param id Primary key of the Brewer
     * @return An instance of Brewer
     */
    public Brewer getBrewerById(Long id) {
        try {
            Optional<Brewer> brewer = brewerService.findOne(id);
            if (brewer.isPresent()) {
                brewer.get().getbeers();
                return brewer.get();
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
        return null;
    }
</code>

Here again, this class implements <code>GraphQLQueryResolver</code>, which allows GraphQL schema to resolve these methods. Remember that these are <code>Get</code> type methods <em>returning</em> data and not <em>changing</em> it.
<h3>GraphQL Schema</h3>
Now, it's time to configure GraphQL to know what methods and models are available. We do this by adding a <code>schema.graphqls</code> file at the project’s root in the resources folder. It’s in the same place as the <code>application.properties</code> file.

Below is the content we need:

<code>
type Brewer {
    id: ID!
    name: String!
    beers: [Beer]!
} 
 
type Beer {
    id: ID!
    title: String!
    brewer: Brewer!
}

# Mutation: to add entities
type Mutation {
    addBrewer(name: String!): Brewer!
    addBeer(title: String!, brewerId:Int!): Beer!
}
 
# The Root Query for the application
type Query {
    brewerById(id:Int): Brewer
    beerById(id:Int): Beer
    getAllBeers: [Beer]
}

</code>

Let’s break this down briefly:
<ul>
 	<li>The <code>types</code> are the “models” for the objects.</li>
 	<li>The <code>mutation</code> is the data changing methods.</li>
 	<li>The <code>query</code> is the definition of methods available to pull data.</li>
 	<li>The exclamation point means the value cannot be empty.</li>
 	<li>Brackets point to arrays. (Most developers will see this as straightforward.)</li>
</ul>
<h3>Go in and Run the Spring Boot Application with GraphQL</h3>
If you have problems, it's probably due to mismatching between the resolvers and the schema file. In a browser, go to <code>localhost:8080/graphiql</code>, and it should show you something like this:
![GraphiQL](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/shb397jo1nmwu5be1pwg.png)

Congratulations! You did it. Now you are on your way to GraphQL greatness!

So this output is simply telling you what is available on your GraphQL. Remove what is there, and write these:

<code>
mutation addBrewery {
  addBrewer(name:"Leinenkugel") {
    id
    name
  }
}

mutation addBrewsky {
  addBeer(title:"Summer Shandy", brewerId:1) {
    id
    title
  }
}

query allBreweries {
 	getAllBeers {
    id
    title
    brewer {
      id
      name
    }
  }
}
</code>

The <code>mutation</code> word tells you what your GraphQL is going to do. Then, the <code>addBrewery</code> is whatever you want it to be.

<code>
mutation addBrewery {
  addBrewer(name:"Leinenkugel") {
    id
    name
  }
}
</code>

The <code>addBrewer</code> is the actual method that you are going to be calling. You pass fields inside the brackets.

Hint: the GraphiQL tool tells you what is available, what it is expecting, and the available fields for return. You must fill in what you want to be returned, or it will complain.

<code>
mutation addBrewery {
  addBrewer(name:"Leinenkugel") {
    id
    name
  }
}
</code>

<h3>The results are JSON:</h3>

<code>
{
  "data": {
    "addBrewer": {
      "id": "1552",
      "name": "Leinenkugel"
    }
  }
}
</code>

<h2>A Few Advantages of Spring Boot with GraphQL</h2>
Just think of it in this way: your API has a table return that typically returns 100 fields. Not efficient!

With GraphQL, you can specify that you only want a handful of fields. It will adjust the query to only request and return the fields you are looking for.

This also allows you to make simpler CRUD functions that only return everything but let GraphQL and the request define what you want from that implementation.

Combining REST calls; although no example is given here, you can combine multiple requests into a simplified request limiting the number of requests that a requester has to make to your API.
<h2>Conclusion</h2>
Although this article is not a complete discussion of what you can accomplish with GraphQL, it gives you a rough look at it in respect to Spring Boot. It will ultimately be a game-changer for many developers who want to stay at the top of their game. If you've found yourself intrigued with Spring Boot with GraphQL and would like to learn more, here is a course on the <a href="https://keyholesoftware.com/learning-services/courses/graphql-course/">fundamentals of GraphQL</a> that provides a more in-depth introduction to this query language.

Please feel free to post any questions or examples where you have used this. I’m looking forward to using this in the near future!
<h3>Resources:</h3>
<a href="https://gitlab.com/mmccandless/boot-graphql">https://gitlab.com/mmccandless/boot-graphql</a>