Introduction
In the earlier article, we talked about GraphQL getting popularity replacing REST and did some comparison between those two. In this article, we will build a sample app for GraphQL and see how to create APIs using GraphQL server and client. GraphQL servers can be built using NodeJS, Spring, and other supported frameworks. In another article, we already explored the GraphQL with Express-NodeJS. In this article, We are going to do that using the Spring Boot with graphql java tools library.
Like an earlier article, we are going to build an API for Class and Student resources. We will also define some relationships between class and students to see the power of GraphQL. In this example, we will show how a class can have multiple students and can be queried accordingly.
Pre-requisites
- Familiarity with Spring boot
- Any IDE
- Familiarity with Maven build
- A MongoDB database - You can use MongoDB atlas which gives a free account and sufficient for this article.
In this article, we will just explore the GraphQL server only. A client can be built using apollo or relay as per your need. You can see the sample implementation in the earlier article.
GraphQL Server
The server is like an API that will implement the functionality for each graphql query by integrating with DB, third party services, etc... It is a bit different from the express-nodejs setup as spring boot has come up with the graphql-java-tools library to eliminate the configuration of a huge boilerplate code.
Step 1 - Set up a Maven Dependency
- spring-boot-starter-web - It is a standard library for a spring boot application to bring all the dependencies together required for a web application.
- spring-boot-starter-data-mongodb -This jar is required for spring data implementation with mongodb entity classes.
- graphql-spring-boot-starter - It is used for enabling GraphQL servlet, and it becomes available at a path /graphql. This path value can be customized by updating the properties in application.properties. It initializes the GraphQLSchema bean. It will add
graphql-java
andgraphql-java-servlet
as dependencies of your project. - graphql-java allows us to write schema with GraphQL schema language, which is simple to understand.
- graphiql-spring-boot-starter - It provides a user interface with which GraphQL queries can be tested and can view query definitions. It exposes /graphiql endpoint.
- graphql-java-tools - This is the most important library. This library works magically to parse GraphQL Schema and map the GraphQL objects with your own POJOs (Entity classes)
Step 2 - Application Properties
Add properties for the MongoDB connection:
Step 3 - Define GraphQL Schema
GraphQL comes with its own language to write GraphQL Schemas called Schema Definition Language (SDL). The schema definition consists of all the API functionalities available at an endpoint.
Add the required Query and Mutation Schema around Classes and Students Collections. This file has to be kept in the resources folder with graphqls extension.
Step 4 - Define Document Entities for MongoDB
Define both students and classes Document. the id field is auto-generated.
Step 5 - Define Repositories
Now, define the repositories for both the documents:
There is one extra method findBy_id has been added to search the StudentClass and Students by _id field. As _id field is ObjectId type in MongoDB, it has to be defined this way to get work.
Another method has been added to Student Repository to get the list of students by searching with a classid.
Step 6 - Define Service Implementation
We need to implement the Student and Class service implementation with repository calls. Example of StudentService implementation:
Step 7 - Define Resolvers
Query or Mutation objects are root GraphQL objects. They need resolvers to map the fields defined in root types. These resolvers have methods that will be called when those root type fields are requested.
For example, In Query root type, we have a field called students so the resolver class which implements GraphQLQueryResolver needs to have a method with name getStudents() or students() with similar signature defined in the schema. If it doesn't find, it should through a runtime error.
Mutation - Mutation is used to insert and update the records. GraphQL Java has specific resolver GraphQLMutationResolver for Mutation handling.
Query - GraphQL Java has specific resolver GraphQLQueryResolver to handle all the query schemas
There is no resolver required for graphql scalar types like Int, String, etc.. However, for a complex object, a separate resolver will be required. For example, StudentClass which is referred by classes field in Query type has students field. To resolve the students field, it would need GraphQLResolver.
Test the GraphQL Server
We can launch the graphiql UI using http://localhost:8080/graphiql
We can pass the graphql compatible input queries in that and test all the queries.
Summary
We have built a simple Spring boot app with GraphQL java library. With the help of graphql-java-tools, we avoided the implementation of DataFetchers, RuntimeWiring, and other classes. The implementation is very straightforward and can work with any Database, Entities, POJOs.
As usual, the code can be found on GitHub: graphql-java
No comments: