Building a Complete CRUD API with Spring Boot and H2 Database


Building a CRUD (Create, Read, Update, Delete) API is one of the foundational skills every backend developer should master. In this tutorial, we’ll walk through building a full-fledged CRUD REST API using Spring Boot and the in-memory H2 database.
This project is perfect for beginners who want to practice backend development without setting up an external database.
✅ What You’ll Build
We’ll create a simple Employee Management API with the following endpoints:
POST /employees
– Create a new employeeGET /employees
– Get all employeesGET /employees/{id}
– Get a single employee by IDPUT /employees/{id}
– Update employee infoDELETE /employees/{id}
– Delete employee
🛠️ Technologies Used
Java 17+
Spring Boot 3.x
Spring Web
Spring Data JPA
H2 Database
📦 Step 1: Set Up the Project
Visit https://start.spring.io and generate a new Maven project with:
Dependencies:
Spring Web
Spring Data JPA
H2 Database
Group: com.example
Artifact: crudapi
Extract and open the project in your IDE (e.g., IntelliJ or Eclipse).
📁 Step 2: Define the Entity
Create an Employee
entity in com.example.crudapi.model
:
package com.example.crudapi.model;
import jakarta.persistence.*;
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String role;
// Constructors
public Employee() {}
public Employee(String name, String role) {
this.name = name;
this.role = role;
}
// Getters & Setters
public Long getId() { return id; }
public String getName() { return name; }
public String getRole() { return role; }
public void setId(Long id) { this.id = id; }
public void setName(String name) { this.name = name; }
public void setRole(String role) { this.role = role; }
}
🧩 Step 3: Create the Repository
Create a simple JPA repository in com.example.crudapi.repository
:
package com.example.crudapi.repository;
import com.example.crudapi.model.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
public interface EmployeeRepository extends JpaRepository<Employee, Long> {}
🎯 Step 4: Build the Service Layer (Optional but Recommended)
package com.example.crudapi.service;
import com.example.crudapi.model.Employee;
import com.example.crudapi.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 repository;
public List<Employee> getAll() {
return repository.findAll();
}
public Optional<Employee> getById(Long id) {
return repository.findById(id);
}
public Employee create(Employee employee) {
return repository.save(employee);
}
public Employee update(Long id, Employee updated) {
return repository.findById(id)
.map(e -> {
e.setName(updated.getName());
e.setRole(updated.getRole());
return repository.save(e);
})
.orElseThrow(() -> new RuntimeException("Employee not found"));
}
public void delete(Long id) {
repository.deleteById(id);
}
}
🌐 Step 5: Create the Controller
package com.example.crudapi.controller;
import com.example.crudapi.model.Employee;
import com.example.crudapi.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/employees")
public class EmployeeController {
@Autowired
private EmployeeService service;
@GetMapping
public List<Employee> getAll() {
return service.getAll();
}
@GetMapping("/{id}")
public Employee getById(@PathVariable Long id) {
return service.getById(id)
.orElseThrow(() -> new RuntimeException("Employee not found"));
}
@PostMapping
public Employee create(@RequestBody Employee employee) {
return service.create(employee);
}
@PutMapping("/{id}")
public Employee update(@PathVariable Long id, @RequestBody Employee employee) {
return service.update(id, employee);
}
@DeleteMapping("/{id}")
public void delete(@PathVariable Long id) {
service.delete(id);
}
}
⚙️ Step 6: Configure H2 Database
In src/main/resources/
application.properties
:
# H2 DB Settings
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
Access H2 Console at:
➡️ http://localhost:8080/h2-console
Use jdbc:h2:mem:testdb
as JDBC URL.
🚀 Step 7: Run and Test
Run the CrudapiApplication.java
main class.
Use Postman or cURL to test the API:
Create:
POST /employees
with body:{ "name": "Alice", "role": "Engineer" }
Read all:
GET /employees
Read by ID:
GET /employees/1
Update:
PUT /employees/1
with body:{ "name": "Alice Smith", "role": "Senior Engineer" }
Delete:
DELETE /employees/1
✅ Summary
You’ve successfully created a complete CRUD REST API using:
Spring Boot for the framework
Spring Data JPA for persistence
H2 for a lightweight, in-memory database
This is a perfect foundation for building more complex APIs. You can now connect to MySQL/PostgreSQL, add validations, implement DTOs, or secure your API with Spring Security.
Subscribe to my newsletter
Read articles from Jaya Vel Rajan directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Jaya Vel Rajan
Jaya Vel Rajan
Welcome to the captivating world of data! Meet Jaya Vel Rajan(that's me!), an aspiring data analyst and passionate data science enthusiast. My insatiable curiosity fuels their exploration of the power of data. Through my captivating blog, I share my knowledge in a unique and accessible way, making complex concepts a breeze. Join me on this thrilling journey, uncovering insights and shaping the future of data. Follow my blog for inspiring, informative, and dazzling content that will leave you amazed by the boundless possibilities of data! 🌟📊✨