Hey guys in this post, we will learn about creating REST API with Spring Boot, PostgreSQL, JPA, and Hibernate. We will also perform the basic CRUD (Create, Read, Update, Delete) operations.
Spring framework is one of the most popular frameworks in the entire java ecosystem. More than 90% of java enterprise applications using the Spring framework in their production.
Spring Boot is a tool to create Spring applications with zero configuration. Spring boot is getting popular day by day that is because you can create REST APIs and Microservices in no time.
JPA is a Java Persistence API, is the most popular data accessor API. It is also getting popular day by day. Almost all the spring boot applications using JPA to access the database data access layer. JPA is just a standard/specification and Hibernate is the implementation.
Table of Contents
Application features
So as part of this tutorial, we will be creating a Customer Relationship Management (CRM) API, it has the following features –
- Create customer
- Read single customer
- Read all customers
- Update customer
- Delete customer
Let’s see the rest endpoints for the above features –
Install PostgreSQL
To install PostgreSQL on your system you can watch the below video –
Development steps
Following are the development steps to create the spring boot REST API.
Create spring boot application
There are different ways to create a spring boot application. You can pick any one of the following ways to create –
>> Create spring boot application using Spring initializer
>> Create spring boot application in Spring tool suite [STS]
>> Create spring boot application in IntelliJ IDEA
Update maven dependencies
Once the project is created open pom.xml
and add the following maven dependencies
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>in.bushansirgur</groupId>
<artifactId>springbooth2database</artifactId>
<version>v1</version>
<name>springbooth2database</name>
<description>Spring boot rest api h2 database</description>
<properties>
<java.version>1.8</java.version>
</properties>
<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>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Configure database
As we have added PostgreSQL dependency to the pom.xml
, so let’s configure the database URL, username, and password. We will also configure hibernate properties for auto-creating the tables based on the entity. Open application.properties
and add the following code –
spring.datasource.url=jdbc:postgresql://localhost:5432/springbootcrm
spring.datasource.username=postgres
spring.datasource.password=root
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=update
Note that, change the spring.datasource.username
and spring.datasource.password
as per your PostgreSQL installation. Also, create a database with the name springbootcrm
Create an entity
Create Customer.java
class inside the in.bushansirgur.springboot.entity
package and add the following fields
package in.bushansirgur.springboot.entity;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Entity
@Table(name="tbl_customer")
@Setter
@Getter
@ToString
public class Customer {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String name;
private Long age;
private String location;
@CreationTimestamp
@Column(name="created_at", nullable=false, updatable=false)
private Date createdAt;
@UpdateTimestamp
@Column(name="updated_at")
private Date updatedAt;
}
@Entity
annotation must be added to the entity class, it tells that the entity class is mapped to the database table
@Table
annotation is added to tell the name of the table to which the class is mapped to.
@Id
annotation is added to make the field uniquely identified, its nothing but the primary key
@GeneratedValue
annotation is added for auto-generating the primary key
@Column
annotation is added to specify the column name. If you don’t provide @Column
annotation then the field name will become the column name.
@CreationTimestamp
annotation automatically adds the current date-time when a new object is created
@UpdateTimestamp
annotation automatically adds the current date-time when an existing object is updated.
@Setter
is a Lombok annotation, which will generate the setters. Similarly, @Getter
will generate the getters and @ToString
will override the toString()
Create JPA repository
Create ICustomerRepo.java
interface inside the package in.bushansirgur.springboot.repository
and add the following code
package in.bushansirgur.springboot.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import in.bushansirgur.springboot.entity.Customer;
@Repository
public interface ICustomerRepo extends JpaRepository<Customer, Long> {
}
Spring Data JPA comes with several interfaces to access the database, one of the interfaces is JpaRepository
, it provides some of the useful methods to perform the database operations such as Create, Read, Update and Delete
Create a controller to handle requests
Create CustomerController.java
class inside in.bushansirgur.springboot.controller
package and add the following code
package in.bushansirgur.springboot.controller;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import in.bushansirgur.springboot.entity.Customer;
import in.bushansirgur.springboot.repository.ICustomerRepo;
@RestController
public class CustomerController {
@Autowired
ICustomerRepo customerRepo;
@PostMapping("/customers")
public ResponseEntity<Customer> save(@RequestBody Customer customer) {
try {
return new ResponseEntity<>(customerRepo.save(customer), HttpStatus.CREATED);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/customers")
public ResponseEntity<List<Customer>> getAllCustomers() {
try {
List<Customer> list = customerRepo.findAll();
if (list.isEmpty() || list.size() == 0) {
return new ResponseEntity<List<Customer>>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<List<Customer>>(list, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/customers/{id}")
public ResponseEntity<Customer> getSingleCustomer(@PathVariable Long id) {
Optional<Customer> customer = customerRepo.findById(id);
if (customer.isPresent()) {
return new ResponseEntity<Customer>(customer.get(), HttpStatus.OK);
}
return new ResponseEntity<Customer>(HttpStatus.NOT_FOUND);
}
@PutMapping("/customers/{id}")
public ResponseEntity<Customer> updateCustomer(@RequestBody Customer customer) {
try {
return new ResponseEntity<Customer>(customerRepo.save(customer), HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@DeleteMapping("/customers/{id}")
public ResponseEntity<HttpStatus> deleteCustomer(@PathVariable Long id) {
try {
Optional<Customer> customer = customerRepo.findById(id);
if (customer.isPresent()) {
customerRepo.delete(customer.get());
}
return new ResponseEntity<HttpStatus>(HttpStatus.NO_CONTENT);
} catch (Exception e) {
return new ResponseEntity<HttpStatus>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
Run the application
Now we have created the REST API for customer relationship management. It’s time to run the application. There are two ways to run the spring boot application
- By executing the maven command from the root of the application
$ mvn spring-boot:run
- By running the java class
Open SpringdatajpaApplication.java
class, it has a main()
method. Run the file just like running any other java class.
In a few seconds, the application will start running on port 8080 (localhost:8080
)
Test the REST API
We cannot test all the rest endpoints inside the browser. Instead, we will use Postman to test all of the rest endpoints.
Hi! No good practice to learn any Java project with Lombok 🙁
Anyway, thanks 😉