Building an Employee Management System with GraphQL and Spring Boot
Tags: webdev, programming, java, springboot
Published: 2024-06-03 12:26:34

# 
In today's rapidly evolving tech landscape, efficient data querying and manipulation are crucial. GraphQL, a query language for APIs, provides a more flexible and powerful alternative to REST. When combined with Spring Boot, a popular framework for building Java applications, you get a robust and efficient system for managing data. In this blog, we'll walk through building an Employee Management System using GraphQL and Spring Boot.

## Table of Contents
1. [Introduction to GraphQL and Spring Boot](#introduction-to-graphql-and-spring-boot)
2. [Setting Up the Project](#setting-up-the-project)
3. [Configuring Spring Boot and GraphQL](#configuring-spring-boot-and-graphql)
4. [Defining the GraphQL Schema](#defining-the-graphql-schema)
5. [Creating the Employee Entity](#creating-the-employee-entity)
6. [Building the Repository Layer](#building-the-repository-layer)
7. [Implementing the Service Layer](#implementing-the-service-layer)
8. [Developing GraphQL Resolvers](#developing-graphql-resolvers)
9. [Testing the API](#testing-the-api)
10. [Conclusion](#conclusion)

## Introduction to GraphQL and Spring Boot

**GraphQL** is a query language for APIs that allows clients to request exactly the data they need, making APIs fast and flexible. It was developed by Facebook and is now an open-source project.

**Spring Boot** is an open-source Java-based framework used to create microservices. It is easy to set up and enables rapid application development.

Combining these two technologies allows developers to build efficient and flexible data APIs.

## Setting Up the Project

First, ensure you have the necessary tools installed:
- JDK 11 or later
- Maven
- An IDE (IntelliJ IDEA, Eclipse, etc.)

Create a new Spring Boot project using Spring Initializr (https://start.spring.io/):
- Project: Maven Project
- Language: Java
- Spring Boot: Latest stable version
- Dependencies: Spring Web, Spring Data JPA, H2 Database, GraphQL Spring Boot Starter

Download the project and import it into your IDE.

## Configuring Spring Boot and GraphQL

In the `pom.xml` file, ensure the following dependencies are included:

```xml
<dependencies>
    <!-- Spring Boot dependencies -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- H2 Database dependency -->
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
    </dependency>

    <!-- GraphQL dependencies -->
    <dependency>
        <groupId>com.graphql-java-kickstart</groupId>
        <artifactId>graphql-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>com.graphql-java-kickstart</groupId>
        <artifactId>graphiql-spring-boot-starter</artifactId>
    </dependency>
</dependencies>
```

Configure the database in `src/main/resources/application.properties`:

```properties
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.h2.console.enabled=true
spring.jpa.hibernate.ddl-auto=update
```

## Defining the GraphQL Schema

Create a directory `src/main/resources/graphql` and add a file `schema.graphqls`:

```graphql
type Query {
    getAllEmployees: [Employee]
    getEmployeeById(id: ID!): Employee
}

type Mutation {
    createEmployee(employeeInput: EmployeeInput): Employee
    updateEmployee(id: ID!, employeeInput: EmployeeInput): Employee
    deleteEmployee(id: ID!): Boolean
}

type Employee {
    id: ID!
    firstName: String!
    lastName: String!
    email: String!
    department: String!
}

input EmployeeInput {
    firstName: String!
    lastName: String!
    email: String!
    department: String!
}
```

## Creating the Employee Entity

Define the `Employee` entity in `src/main/java/com/example/employeemanagement/model/Employee.java`:

```java
package com.example.employeemanagement.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Employee {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String firstName;
    private String lastName;
    private String email;
    private String department;

    // Getters and Setters
}
```

## Building the Repository Layer

Create the repository interface in `src/main/java/com/example/employeemanagement/repository/EmployeeRepository.java`:

```java
package com.example.employeemanagement.repository;

import com.example.employeemanagement.model.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}
```

## Implementing the Service Layer

Create the service class in `src/main/java/com/example/employeemanagement/service/EmployeeService.java`:

```java
package com.example.employeemanagement.service;

import com.example.employeemanagement.model.Employee;
import com.example.employeemanagement.repository.EmployeeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service
public class EmployeeService {

    @Autowired
    private EmployeeRepository employeeRepository;

    public List<Employee> getAllEmployees() {
        return employeeRepository.findAll();
    }

    public Optional<Employee> getEmployeeById(Long id) {
        return employeeRepository.findById(id);
    }

    public Employee createEmployee(Employee employee) {
        return employeeRepository.save(employee);
    }

    public Employee updateEmployee(Long id, Employee employeeDetails) {
        Employee employee = employeeRepository.findById(id).orElseThrow(() -> new RuntimeException("Employee not found"));

        employee.setFirstName(employeeDetails.getFirstName());
        employee.setLastName(employeeDetails.getLastName());
        employee.setEmail(employeeDetails.getEmail());
        employee.setDepartment(employeeDetails.getDepartment());

        return employeeRepository.save(employee);
    }

    public boolean deleteEmployee(Long id) {
        Employee employee = employeeRepository.findById(id).orElseThrow(() -> new RuntimeException("Employee not found"));
        employeeRepository.delete(employee);
        return true;
    }
}
```

## Developing GraphQL Resolvers

Create the GraphQL resolvers in `src/main/java/com/example/employeemanagement/resolver`:

1. **Query Resolver**

   ```java
   package com.example.employeemanagement.resolver;

   import com.coxautodev.graphql.tools.GraphQLQueryResolver;
   import com.example.employeemanagement.model.Employee;
   import com.example.employeemanagement.service.EmployeeService;
   import org.springframework.beans.factory.annotation.Autowired;
   import org.springframework.stereotype.Component;

   import java.util.List;

   @Component
   public class Query implements GraphQLQueryResolver {

       @Autowired
       private EmployeeService employeeService;

       public List<Employee> getAllEmployees() {
           return employeeService.getAllEmployees();
       }

       public Employee getEmployeeById(Long id) {
           return employeeService.getEmployeeById(id).orElse(null);
       }
   }
   ```

2. **Mutation Resolver**

   ```java
   package com.example.employeemanagement.resolver;

   import com.coxautodev.graphql.tools.GraphQLMutationResolver;
   import com.example.employeemanagement.model.Employee;
   import com.example.employeemanagement.service.EmployeeService;
   import com.example.employeemanagement.input.EmployeeInput;
   import org.springframework.beans.factory.annotation.Autowired;
   import org.springframework.stereotype.Component;

   @Component
   public class Mutation implements GraphQLMutationResolver {

       @Autowired
       private EmployeeService employeeService;

       public Employee createEmployee(EmployeeInput employeeInput) {
           Employee employee = new Employee();
           employee.setFirstName(employeeInput.getFirstName());
           employee.setLastName(employeeInput.getLastName());
           employee.setEmail(employeeInput.getEmail());
           employee.setDepartment(employeeInput.getDepartment());
           return employeeService.createEmployee(employee);
       }

       public Employee updateEmployee(Long id, EmployeeInput employeeInput) {
           Employee employeeDetails = new Employee();
           employeeDetails.setFirstName(employeeInput.getFirstName());
           employeeDetails.setLastName(employeeInput.getLastName());
           employeeDetails.setEmail(employeeInput.getEmail());
           employeeDetails.setDepartment(employeeInput.getDepartment());
           return employeeService.updateEmployee(id, employeeDetails);
       }

       public boolean deleteEmployee(Long id) {
           return employeeService.deleteEmployee(id);
       }
   }
   ```

3. **Employee Input Class**

   ```java
   package com.example.employeemanagement.input;

   public class EmployeeInput {

       private String firstName;
       private String lastName;
       private String email;
       private String department;

       // Getters and Setters
   }
   ```

## Testing the API

Run the application using your IDE or by executing `mvn spring-boot:run` in the terminal.

Open your browser and navigate to `http://localhost:8080/graphiql` to access the GraphiQL interface for testing GraphQL queries and mutations.

**Sample Queries:**

- Get all employees

:
  ```graphql
  query {
      getAllEmployees {
          id
          firstName
          lastName
          email
          department
      }
  }
  ```

- Get an employee by ID:
  ```graphql
  query {
      getEmployeeById(id: 1) {
          id
          firstName
          lastName
          email
          department
      }
  }
  ```

**Sample Mutations:**

- Create an employee:
  ```graphql
  mutation {
      createEmployee(employeeInput: {
          firstName: "John"
          lastName: "Doe"
          email: "john.doe@example.com"
          department: "Engineering"
      }) {
          id
          firstName
          lastName
          email
          department
      }
  }
  ```

- Update an employee:
  ```graphql
  mutation {
      updateEmployee(id: 1, employeeInput: {
          firstName: "Jane"
          lastName: "Doe"
          email: "jane.doe@example.com"
          department: "HR"
      }) {
          id
          firstName
          lastName
          email
          department
      }
  }
  ```

- Delete an employee:
  ```graphql
  mutation {
      deleteEmployee(id: 1)
  }
  ```

## Conclusion

In this blog, we walked through building an Employee Management System using GraphQL and Spring Boot. We covered setting up the project, configuring GraphQL, defining the schema, creating entities, building the repository and service layers, implementing GraphQL resolvers, and testing the API. This combination of technologies provides a powerful and flexible way to handle data in modern applications.