Rest Api with Springboot
Introduction
Developing a robust and efficient REST API is a fundamental requirement for many modern web applications. Spring Boot, a popular Java framework, simplifies the process of building RESTful APIs by providing a convention-over-configuration approach and a wealth of built-in features. In this article, I will guide you through the process of creating a REST API using Spring Boot.
Adding dependancies
You need to make sure you have the necessary maven dependencies installed in your pom.xml file. I presume you already downloaded the springboot template from spring initializer
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
Configuring the database
Next we need to configure our springboot app to the database so that the data created can be accessed on our database.
Ensure you have created a database already. For instance, in our case we are using MYSQL database to create database named RestApis
. The configuration is done on the application.properties file.
spring.datasource.username=root
spring.datasource.password=Wababe8843
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=create
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
Creating Employee entity class
After configuring the database we are ready to create the entity class so that we can add the attributes that we gonna be using while testing the apis. For this tutorial lets create an Employee Table.
package com.alekinyua.restapiexceptions.entity;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
private int age;
}
In the employee table;
We created 4 attributes to save the employee's information.
We also used lombok annotations to remove boilerplate code. For instance,
@Data
was used in place getters, setters and tostring methods,@Entity
is used to identify that this is a table.Also, we must have the necessary constructors in our class i.e the parameter constructor and no parameter construtor. This is done by help of lombok annotation
@NoArgsConstructor
@AllArgsConstructor
We also have to identify the primary key on our table by using the
@Id
annotation
Creating Employee Repository Interface
package com.alekinyua.restapiexceptions.repository;
import com.alekinyua.restapiexceptions.entity.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}
We annotate the interface using the @Repository
annotation. The interface extends the JPa repository to inherit the predefined CRUD operation methods without having to implement them yourself.
Creating the Employee Service class
In this class, we implement the business logic. All the methods are implemented here ie saveEmployee, deleteEmployee, updateEmployee, getAllEmployees and getEmployee.
We need to inject the EmployeeRepository to access the predifined crud operation methods in the jpa repository.
The code below shows implementation of the employee service class.
package com.alekinyua.restapiexceptions.service;
import com.alekinyua.restapiexceptions.entity.Employee;
import com.alekinyua.restapiexceptions.repository.EmployeeRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
@Service
@RequiredArgsConstructor
public class EmployeeService {
private final EmployeeRepository employeeRepository;
public Optional<Employee> getEmployee(Long id) {
return Optional.ofNullable(employeeRepository.findById(id)
.orElseThrow(() -> new NoSuchElementException()));
}
public List<Employee> getAllEmployees() {
List<Employee> employees = employeeRepository.findAll();
return employees;
}
public Employee saveEmployee(Employee employee){
return employeeRepository.save(employee);
}
public Employee updateEmployee(Long id, Employee employeeToUpdate){
Employee employee = employeeRepository.findById(id).get();
employee.setName(employeeToUpdate.getName());
employee.setEmail(employeeToUpdate.getEmail());
employee.setAge(employeeToUpdate.getAge());
return employeeRepository.save(employee);
}
public void deleteEmployee(Long id){
Employee employee = employeeRepository.findById(id).orElseThrow();
if (employee != null){
employeeRepository.delete(employee);
}
}
}
Creating Employee Controller
The @RestController
annotation marks the class as a RESTful controller, indicating that it handles HTTP requests and returns responses.
The @RequiredArgsConstructor
annotation generates a constructor that injects the dependencies, in this case, the EmployeeService
instance.
package com.alekinyua.restapiexceptions.controller;
import com.alekinyua.restapiexceptions.entity.Employee;
import com.alekinyua.restapiexceptions.service.EmployeeService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequiredArgsConstructor
public class EmployeeController {
private final EmployeeService employeeService;
@PostMapping(value = "/employee/save")
public Employee saveEmployee(@RequestBody Employee employee){
return employeeService.saveEmployee(employee);
}
@GetMapping("/employee/{id}")
public Employee getEmployee(@PathVariable("id") Long id){
return employeeService.getEmployee(id).get();
}
@GetMapping("/employees")
public List<Employee> getAllEmployees (){
return employeeService.getAllEmployees();
}
@PostMapping("/edit_employee/{id}")
public Employee updateEmployee(@PathVariable("id") Long id,@RequestBody Employee employee){
return employeeService.updateEmployee(id, employee);
}
@GetMapping("/delete_employee/{id}")
public void deleteEmployee(@PathVariable("id") Long id){
employeeService.deleteEmployee(id);
}
Endpoint Definitions:
The
saveEmployee()
method is mapped to thePOST
request at/employee/save
. It accepts anEmployee
object as a request body and saves it using theemployeeService.saveEmployee()
method.The
getEmployee()
method is mapped to theGET
request at/employee/{id}
. It retrieves the employee with the specifiedid
using theemployeeService.getEmployee(id)
method.The
getAllEmployees()
method is mapped to theGET
request at/employees
. It retrieves a list of all employees using theemployeeService.getAllEmployees()
method.The
updateEmployee()
method is mapped to thePOST
request at/edit_employee/{id}
. It updates the employee with the specifiedid
using theemployeeService.updateEmployee(id, employee)
method.The
deleteEmployee()
method is mapped to theGET
request at/delete_employee/{id}
. It deletes the employee with the specifiedid
using theemployeeService.deleteEmployee(id)
method.