Java and GraphQL: A Guide
Learn how to use Java, Spring Boot, and JUnit 5 to build and test a GraphQL API.
Join the DZone community and get the full member experience.Join For Free
It is quite difficult to design REST APIs as they need to serve multiple clients efficiently. Each client has their own needs, and therefore requires different parameters around data filtering and searching, which is where a traditional rest API comes in. Clients can navigate the single version, picking and choosing the data they want.
Developed by Facebook to overcome the shortcomings of REST API, GraphQL acts as a query language for APIs, as well as a runtime for fulfilling those queries with your extant data. When you provide a complete and clear description of the data in your API, clients can utilize that to ask for exactly what they need. When you expose your schema, the evolution of APIs becomes much easier. Clients can still navigate the schema to fit their needs, even if you add more fields and relations over time.
In this article, I will be walking you through the process of using Java and Spring Boot to build a GraphQL API. In addition, I will also go through the steps to test your GraphQL API using Java’s most popular testing library: JUnit 5.
If you would rather watch a video or follow along with the audio, you can watch this tutorial as a screencast.
Create a GraphQL API With Java and Spring Boot
Let’s start with an initialized app by going to Spring Initializr and defining your app data as follows:
- Project: Maven Project
- Language: Java
- Spring Boot: 2.2.2
- Project Metadata:
- Group: com.oktadeveloper
- Artifact: graphqldemo
- Add Spring Web
- Add Spring Data JPA
- Add H2 Database
You may also follow this link, it will take you to a pre-configured Spring Initializr page.
Expand the downloaded package and add GraphQL SPQR as a dependency to your
Then create a
Food entity class:
Notice that you are already using GraphQL SPQR (GraphQL Schema Publisher & Query Resolver, pronounced like speaker) annotations (i.e.
@GraphQLQuery) on the entity. This is how it will know to expose those entities in the API.
Create the respective repository:
In GraphQL you can either define a query which will only load data, or define a mutation which will also change the underlying data that feeds the API. For this sample app, you will define the basic read, save and delete functionality for food entities. For that, create a service class:
Notice that you are also able to define calculated properties to entities. In the above class, you declared the method
isGood() as a property that can be queried for each food. You will see ahead that you can read it just like you read the food’s
To initialize the app with sample data, add an
ApplicationRunner bean definition in
Also, add the following line to
application.properties to enable the web UI to test the GraphQL API:
Run Your Java GraphQL API
Run the project with
./mvnw spring-boot:run. Head over to
http://localhost:8080/gui and you should see a web UI to test your GraphQL API. Run a sample query by typing on the left-side panel:
Click the play button and you should see a result similar to this:
You can also find a specific food by ID using a query like the following:
And seeing that result:
Notice that you are able to manipulate the response. On that last query, you asked only for the
name of the food and the API didn’t return the
id nor the
Create a new food by running the
And you will see a result like:
If you query all the foods again you should see the newly added “Pasta” there.
Test Your Java GraphQL API with JUnit 5
You can write tests for your API with JUnit 5 and Spring Mock MVC. To do this, you can call your API via HTTP, wrap the query in a JSON object with a single property called
"query", and the response should be similar to what you were seeing in the web UI. For example, the following class tests that you can retrieve all registered foods:
You can replace
src/test/java/com/.../GraphqldemoApplicationTests.java with the code above and run
./mvnw test to see it in action.
For a client to use your GraphQL API, it just needs to call it as a standard HTTP API: send a POST request with the query or mutation and parse the result as JSON.
Secure Your Java GraphQL API
So far, your API is open to whoever has its endpoint URI. Let’s change that by adding proper security.
Okta offers a very handy Maven plugin to set up your app’s security quickly and easily. First, add Okta as a dependency in
pom.xml. While you’re at it, add Spring Security’s testing library.
Then run the Okta Maven plugin from your app’s folder:
Answer a few questions (name, email, and company), and it will generate a new Okta developer account for you.
Run the following command to register a new OIDC application, and add the correct properties into your
If you start your app again, you’ll notice that you can’t run GraphQL queries anymore. That’s because you’re not authenticated.
To authenticate and see your access token (required to use the API), create a very simple controller that displays the access token. Add the following class to your project:
Start your app again and go to
http://localhost:8080/my-access-token. If you are not authenticated, it will present you with a login form. After authenticating, you will see your token displayed on the web page. Copy the token value as you will use it next.
If you want to use the web UI (
http://localhost:8080/gui), click on HTTP HEADERS at the bottom left and add the following, replacing
<your_access_token> with the actual value of your access token that you got in the previous step:
If you are calling the API directly through HTTP, simply add the
Authorization header with value
Bearer <your_access_token>. You can click the
Copy CURL button in the top right of the web UI to see an example.
Or you can use HTTPie:
Now you have a fully secured GraphQL API!
If you try running your tests (
./mvnw test), you will notice they are failing because the API will now answer with 403 Forbidden instead of 200 OK:
That happens because your tests are not security-aware. To fix that, you need to add the method call
.with(SecurityMockMvcRequestPostProcessors.jwt()) to each of your
mockMvc.perform() chains, for example:
SecurityMockMvcRequestPostProcessors.jwt() can be static imports, so you can make this code a bit easier to read. Add the imports:
Then remove the class names from the test:
jwt() method instructs the test to inject a JWT authentication and act accordingly as if a user is authenticated.
Below is a full test class that verifies the GraphQL API you wrote works as expected:
Further Reading on GraphQL and Java
In this tutorial, you learned how to create your GraphQL API in Java with Spring Boot. But you are not limited to Spring Boot for that. You can use the GraphQL SPQR in pretty much any Java environment, even with Micronaut.
If you are using Quarkus and natively compiling your code, GraphQL SPQR wouldn’t work as it depends on reflection. But on that environment (and others) you could use the less-magic GraphQL Java, it’s a bit more verbose as you need to manually declare your schema, but it gets the job done as well as GraphQL SPQR. And don’t worry, we have a tutorial for GraphQL Java as well:
If you want to keep reading about Java, Security, and Spring, here are some other links for you:
- Build a Java REST API with Java EE and OIDC
- Java + Spring Tutorials
- 10 Myths About Java in 2019
- Use React and Spring Boot to Build a Simple CRUD App
The source code for this post is available on GitHub in the oktadeveloper/okta-graphql-java-example repository.
Published at DZone with permission of Thiago Negri. See the original article here.
Opinions expressed by DZone contributors are their own.