Build a GraphQL Server With Spring Boot and MySQL
By: Yasas Sandeepa
Tags: Spring Boot, MySQL, Programming, Coding, GraphQL

Releasing The Beast: Setting Up GraphQL

First things first! You need to add GraphQL dependencies to the project.

So in the pom.xml add these two dependencies inside the <dependencies> section and update the project (resolve dependencies) by clicking the m icon in the top right corner.

<!-- GraphQL dependencies -->

<dependency>

<groupId>com.graphql-java</groupId>

<artifactId>graphql-spring-boot-starter</artifactId>

<version>5.0.2</version>

</dependency>

<dependency>

<groupId>com.graphql-java</groupId>

<artifactId>graphql-java-tools</artifactId>

<version>5.2.4</version>

</dependency>

Screenshot provided by the author.

GraphQL has two main building blocks: schema and resolver. As the first step of implementing GraphQL to our app, we need to define a schema.

The most basic components of a GraphQL schema are object types, which represent an object (like student, animal, etc.) that you can fetch from your service, and what fields it has.

type Director {

name: String!

age: Int

films: [Film]

}

As you know there are so many primitive and non-primitive data types in languages like java. But here we can see only a limited number of data types (known as scalar types).

Int: A signed 32‐bit integer.

Float: A signed double-precision floating-point value.

String: A UTF‐8 character sequence.

Boolean: true or false.

ID: A unique identifier

However, you can define custom scalars according to your preference.

(like Date, Currency, etc..)

Most types in your schema will just be normal object types, but there are two types that are special within a schema.

Query: Entry point of data fetching (Read) Mutation: Entry point of data modifying (Write)

You can learn more about these concepts by visiting the official GraphQL web site.

Okay. Let’s define our schema. For that, I created a directory named graphql inside the resource folder and created a schema.graphqls file inside of it. (Make sure the extension should be .graphqls as it’s a schema file.)

If you already installed the GraphQL plugin to IntelliJ, you can see the GraphQL icon after creating the file. It can easily install by searching in the plug-in section. It would be so much useful when doing the

development of a GraphQL schema file.

Screenshot provided by the author.

Here is the schema that I defined for my writeup application. First I go with a query and it will be easy to understand the things from it and then I’ll explain the mutation.

schema {

query: Query,

} type Query{

# Fetch All Users

getAllUsers:[User]

} type User {

userId : ID!,

firstName :String,

lastName :String,

dob:String,

address:String,

postId : Int,

}

Make sure to add comments as here. For the reason that, we can view those descriptions when testing the server with third-party tools like Altair (Mostly we are using this client for testing GraphQL endpoints instead of postman.)

Now we have to define our resolvers. (If you are curious about what is this getAllUsers method [not a method but a field] and where it’s referencing, wait this is it)

Resolvers are per field functions that are given a parent object, arguments, and the execution context. They are responsible for returning the corresponding data result for that field.

We can implement this in multiple ways. Most larger projects (Industry standard) tend to create a separate graphql package inside the root layer and inside that, it will define resolver interfaces and implementations. Also, mapping types for requests and responses can be defined in separate packages.

Industry Standard for defining resolvers

As this is for understanding the concepts, I’ll implement this on the service layer.

I created a new service called UserService and implement GraphQLQueryResolver interface that comes as a library interface in graphql-java-tools

Then I auto-wired the user repository to get a connection with the database. (However, this field injection is not recommended in the latest versions. What you can do is, click on the yellow color bulb icon in the left corner when appears by clicking on the Autowired annotation and reformat as idea suggest.)

Now hope you remember that getAllUsers field we defined in the GraphQL schema. That should exactly tally with the method of this class. So I defined that method here and returned the user list as expected.

Folder structure and the service layer

Finally, we have to define our GraphQL configurations in the application.properties file.

#graphql properties

graphql.servlet.corsEnabled=true

graphql.servlet.mapping=/graphql

graphql.servlet.enabled=true

As you can see from the configs, /graphql endpoint will be handling all the requests. So you don’t need to define a controller.

All set! Our server is ready now. Give a test run and voila: you will be seeing such a message like “Started WriteupApplication...(JVM running…)”

So now the testing. As I mentioned previously, you can use Altair client to test those endpoints. It comes as a desktop app and as well as a browser extension. You can add this to your machine as your preference by clicking here.

Now go to the server endpoint using Altair.

If you reload the docs section, you can see the fields with the comment message. You can click it and look for more details. Write a query inside the left corner. You can see the Altair giving the auto-completion. By clicking the run query or send request buttons, you can get the results.

Screenshot provided by the author.

Look, how cool is that! We can get the details as we request. I hope now you all clear with the concept as well as the practical. I’ll explain about mutation as well as for the completion of my article.

As the first thing, you can add a mutation to the schema file. I have done the update user address as an example. For that, I added the mutation to the schema and defined the mutation as below. So the final schema will be as follows.

I added a SQL query to the user repository to update the user from incoming parameters.

In the user service, we have to implement another interface called GraphQLMutationResolver Then we can define our updateUserAdress method there. Make sure that all the methods can be publicly accessible. So the final UserService will be as follows.

All right! We defined our mutation also. Now do the testing as usual. You can confirm the API is working perfectly by checking the database.

Screenshot provided by the author.

Great! You have completed most concepts in GraphQL. But there are plenty of things we need to explore in this amazing world. Wait, I’ll reveal some more things.

In addition to queries and mutations, GraphQL supports a third operation type called subscriptions.

Like queries, subscriptions enable you to fetch data. Unlike queries, subscriptions maintain an active connection to your GraphQL server. (Most commonly via a Web Socket) This enables your server to push updates to the subscription’s result over time.

This is extremely useful when notifying your client in real-time about alterations to back-end data, such as user notifications, important updates, changes in files, etc.

Also, there are many more things to cover up in GraphQL like error handling, spring-security, validation, etc. So I’ll intend to have separate articles on these topics as well.