Getting Started with GraphQL and Spring Boot

Getting Started with GraphQL and Spring Boot

GraphQL is a query language for APIs that allows clients to request limited data they need, making it possible for clients to gather data in a limited number of requests. In this article, we will build a simple GraphQL server with Spring Boot.

GraphQL is strongly typed protocol and all data operations are validated against a GraphQL schema.

Adding Maven Dependencies

Create a sample Spring Boot application and add the following dependencies.

  1. graphql-spring-boot-starter is used for enabling GraphQL servlet and it becomes available at a path /graphql. It initializes _GraphQLSchema_ bean.
  2. graphql-java allows to write schema with GraphQL schema language which is simple to understand.
  3. graphiql-spring-boot-starter provides user interface using which we could test our GraphQL queries and view query definition.
        <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>
        <dependency>
            <groupId>com.graphql-java</groupId>
            <artifactId>graphiql-spring-boot-starter</artifactId>
            <version>5.0.2</version>
        </dependency>

Here is the complete POM file content.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.techshard.graphql</groupId>
    <artifactId>springboot-graphql</artifactId>
    <version>1.0-SNAPSHOT</version>

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

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <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>
        <dependency>
            <groupId>com.graphql-java</groupId>
            <artifactId>graphiql-spring-boot-starter</artifactId>
            <version>5.0.2</version>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Creating JPA Entity and Repository

Let’s create a simple entity called Vehicle and a corresponding JPA repository. We will use Lombok to avoid writing boilerplates such as getters, setters and so on.

package com.techshard.graphql.dao.entity;

import lombok.Data;
import lombok.EqualsAndHashCode;

import javax.persistence.*;
import java.io.Serializable;
import java.time.LocalDate;

@Data
@EqualsAndHashCode
@Entity
public class Vehicle implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "ID", nullable = false)
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @Column(name = "type", nullable = false)
    private String type;

    @Column(name = "model_code", nullable = false)
    private String modelCode;

    @Column(name = "brand_name")
    private String brandName;

    @Column(name = "launch_date")
    private LocalDate launchDate;

    private transient  String formattedDate;

    // Getter and setter
    public String getFormattedDate() {
        return getLaunchDate().toString();
    }
}

Here is the corresponding JPA repository.

package com.techshard.graphql.dao.repository;

import com.techshard.graphql.dao.entity.Vehicle;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface VehicleRepository extends JpaRepository<Vehicle, Integer> {
}

GraphQL Schema

GraphQL comes with its own language to write GraphQL Schema called Schema Definition Language (SDL). The schema definition consists of all the API functionalities available at an endpoint.

A typical example of GraphQL schema would look like this:

type Vehicle {
    id: ID!,
    type: String,
    modelCode: String,
    brandName: String,
    launchDate: String
}

type Query {
    vehicles(count: Int):[Vehicle]
    vehicle(id: ID):Vehicle
}

type Mutation {
    createVehicle(type: String!, modelCode: String!, brandName: String, launchDate: String):Vehicle
}

Create a folder graphql under src/main/resources and create a file vehicleql.graphqls under that folder. Copy the above contents and paste it in the vehicleql.graphqls file. Note that, the name of the file could be any name of your choice. Just make sure to keep the file extension as .graphqls.

In the above schema, each object is defined with type. The type system in GraphQL is the most basic component and it represents a kind of object that can be fetched from a service and the fields that the object contains within.

In our schema, we have an object called Vehicle which is our domain object. The type Query represents the query that can be made to the GraphQL server to fetch data. This query is interactive, they can be modified, and new results can be seen. The structure of query and result is same. This is important in GraphQL world, because we always get back the result that we expect.

We will see a working example in this article later.

The type Mutation represents the queries that are used to perform write operations on the data.

Root Query

Query or Mutation objects are root GraphQL objects, they don’t have any associated data class. In such cases, the resolver classes would implement GraphQLQueryResolver or GraphQLMutationResolver. These resolvers will be searched for methods that map to fields in their respective root types.

Let’s define root resolvers for Vehicle.

package com.techshard.graphql.query;

import com.coxautodev.graphql.tools.GraphQLQueryResolver;
import com.techshard.graphql.dao.entity.Vehicle;
import com.techshard.graphql.service.VehicleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Optional;

@Component
public class VehicleQuery implements GraphQLQueryResolver {

    @Autowired
    private VehicleService vehicleService;

    public List<Vehicle> getVehicles(final int count) {
        return this.vehicleService.getAllVehicles(count);
    }

    public Optional<Vehicle> getVehicle(final int id) {
        return this.vehicleService.getVehicle(id);
    }
}

In this class, we have methods to get a single Vehicle object and a list of Vehicle objects. Note that, we have defined these methods in our schema above.

Now, let’s define a Mutation resolver.

package com.techshard.graphql.mutation;

import com.coxautodev.graphql.tools.GraphQLMutationResolver;
import com.techshard.graphql.dao.entity.Vehicle;
import com.techshard.graphql.service.VehicleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDate;

@Component
public class VehicleMutation implements GraphQLMutationResolver {

    @Autowired
    private VehicleService vehicleService;

    public Vehicle createVehicle(final String type, final String modelCode, final String brandName, final String launchDate) {
        return this.vehicleService.createVehicle(type, modelCode, brandName, launchDate);
    }
}

In this class, we only have one method to create a Vehicle object and this corresponds to type Mutation in our schema definition.

We will now define a service which would make actual transactions.

package com.techshard.graphql.service;

import com.techshard.graphql.dao.entity.Vehicle;
import com.techshard.graphql.dao.repository.VehicleRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class VehicleService {

    private final VehicleRepository vehicleRepository ;

    public VehicleService(final VehicleRepository vehicleRepository) {
        this.vehicleRepository = vehicleRepository ;
    }

    @Transactional
    public Vehicle createVehicle(final String type,final String modelCode, final String brandName, final String launchDate) {
        final Vehicle vehicle = new Vehicle();
        vehicle.setType(type);
        vehicle.setModelCode(modelCode);
        vehicle.setBrandName(brandName);
        vehicle.setLaunchDate(LocalDate.parse(launchDate));
        return this.vehicleRepository.save(vehicle);
    }

    @Transactional(readOnly = true)
    public List<Vehicle> getAllVehicles(final int count) {
        return this.vehicleRepository.findAll().stream().limit(count).collect(Collectors.toList());
    }

    @Transactional(readOnly = true)
    public Optional<Vehicle> getVehicle(final int id) {
        return this.vehicleRepository.findById(id);
    }
}

Testing the Application

The application is now ready for testing. Run the Spring Boot application. Open the link http://localhost:8080/graphiql in the browser. We will see a nice user interface as below.

Getting Started with GraphQL and Spring Boot

On the right side of user interface, we can also explore documentation.

Getting Started with GraphQL and Spring Boot

Now, run the following query.

mutation {
  createVehicle(type: "car", modelCode: "XYZ0192", brandName: "XYZ", launchDate: "2016-08-16") 
  {
    id
  }
}

This will create a row in the Vehicle table. The result would be:

{
  "data": {
    "createVehicle": {
      "id": "1"
    }
  }
}

Let us now run a query to get the data.

query {
  vehicles(count: 1) 
  {
    id, 
    type, 
    modelCode
    }
}

The output will be:

{
  "data": {
    "vehicles": [
      {
        "id": "1",
        "type": "bus",
        "modelCode": "XYZ123"
      }
    ]
  }
}

Note that we are requesting for only limited number of fields. We can change our query by adding or removing fields and see the new results.

Conclusion

In this article, we looked at the basic concepts of GraphQL. Check out the detailed documentation here.

The complete source code for this tutorial can be found on GitHub.

graphql spring-boot database

What's new in Bootstrap 5 and when Bootstrap 5 release date?

How to Build Progressive Web Apps (PWA) using Angular 9

What is new features in Javascript ES2020 ECMAScript 2020

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Random Password Generator Online

HTML Color Picker online | HEX Color Picker | RGB Color Picker

Spring Boot Tutorials - Spring Boot Full Course

Spring Boot Tutorials | Full Course - What is Spring? Spring Boot is an open source Java-based framework used to create a Micro Service. Spring Boot contains a comprehensive infrastructure support for developing a micro service and enables you to develop enterprise-ready applications that you can “just run”.

How to Build a GraphQL API with Java and Spring Boot

In this tutorial, I’ll show you how to use Java and Spring Boot to build a GraphQL API. How to GraphQL in Java. Create a GraphQL API with Java and Spring Boot. Run Your Java GraphQL API. Test Your Java GraphQL API with JUnit 5. Secure Your Java GraphQL API. Further Reading on GraphQL and Java.

Building a Secure API with GraphQL & Spring Boot

Build a Secure API with Spring Boot and GraphQL. GraphQL is a data query language developed by Facebook in 2012 to solve a shortcoming of REST APIs and traditional database models.

How to Build a simple GraphQL server with Spring-Boot

In this article, we will build a simple GraphQL server with Spring Boot.

How to Build a GraphQL API using Spring Boot

This article will give an introduction to setting up a GraphQL server using Spring Boot so that it can be added to existing applications or used in new ones.