Spring Boot is the industry-standard framework for building modern Java applications. It dramatically reduces boilerplate code, accelerates development, and is battle-tested for microservices and monoliths alike. If you’re new to the Spring ecosystem, this post will walk you through everything you need to start building.
By the end of this guide, you’ll:
- Understand what Spring Boot is and how it differs from Spring
- Generate a project using Spring Initializr
- Create a REST API with CRUD operations
- Use an H2 in-memory database
We’ll build a simple Task Manager API with endpoints to create, read, update, and delete tasks.
What Is Spring Boot?
Spring Boot is an extension of the Spring Framework that simplifies configuration and accelerates development. It embraces convention over configuration and provides:
- Embedded servers (no need to deploy WAR files)
- Auto-configuration
- Production-ready features (health checks, metrics, etc.)
- Easy dependency management
In short, Spring Boot is Spring with batteries included.
Spring vs. Spring Boot
Feature | Spring (Core) | Spring Boot |
---|---|---|
Setup effort | High | Minimal (via Initializr) |
Configuration style | Manual (XML or Java) | Auto-configured + opinionated |
Server setup | External (Tomcat, etc.) | Embedded (Tomcat, Jetty, etc.) |
Deployment | WAR | JAR (self-contained) |
Production readiness | Manual setup | Built-in with Actuator |
Spring Boot builds on top of Spring, making it faster and easier to get started, especially for RESTful web services.
Step 1: Create the Project (Spring Initializr)
Go to https://start.spring.io and set the following:
Group | io.igventurelli |
Artifact | taskmanager |
Project | Maven |
Language | Java |
Spring Boot | 3.4.x |
Packaging | jar |
Java | 17 |
Dependencies | – Spring Web – Spring Data JPA – H2 Database – Spring Boot DevTools |

Generate the project and open it in your IDE.
Step 2: Understand the Generated Structure
src/
├── main/
│ ├── java/io/igventurelli/taskmanager/
│ │ └── TaskManagerApplication.java
│ └── resources/
│ ├── application.properties
TaskManagerApplication.java
is your app’s entry pointapplication.properties
stores configurations- You’ll be adding models, controllers, and repositories next
The main class of a Spring Boot application (in our case,
TaskManagerApplication.java
) serves as the entry point for your app. It is typically annotated with@SpringBootApplication
, which is a convenience annotation that combines@Configuration
,@EnableAutoConfiguration
, and@ComponentScan
. This class contains the main method, which callsSpringApplication.run(...)
to bootstrap the application, initialize the Spring context, and start the embedded server. In short, it’s where everything begins.
Step 3: Create the Task Entity
package io.igventurelli.taskmanager.model;
import jakarta.persistence.*;
@Entity
public class Task {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String description;
private boolean completed;
// Getters and Setters
}
An entity class in Spring Boot represents a table in your database. It is annotated with
@Entity
and typically maps each class field to a column using annotations like@Id
for the primary key and@GeneratedValue
for auto-incrementing values. Entity classes are the foundation of your data model and are used by Spring Data JPA to perform CRUD operations without writing SQL manually.
Step 4: Create the Repository Interface
package io.igventurelli.taskmanager.repository;
import com.example.taskmanager.model.Task;
import org.springframework.data.jpa.repository.JpaRepository;
public interface TaskRepository extends JpaRepository<Task, Long> {}
The repository interface in Spring Boot is where you define data access operations for your entity. By extending
JpaRepository
(orCrudRepository
), you automatically inherit common CRUD methods likesave()
,findById()
,findAll()
, anddelete()
. Spring Data JPA uses generics to understand which entity and primary key type you’re working with, so you can write zero boilerplate code and still interact with the database efficiently.
Step 5: Create the REST Controller
package io.igventurelli.taskmanager.controller;
import com.example.taskmanager.model.Task;
import com.example.taskmanager.repository.TaskRepository;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/tasks")
public class TaskController {
private final TaskRepository repository;
public TaskController(TaskRepository repository) {
this.repository = repository;
}
@GetMapping
public List<Task> getAllTasks() {
return repository.findAll();
}
@PostMapping
public Task createTask(@RequestBody Task task) {
return repository.save(task);
}
@PutMapping("/{id}")
public ResponseEntity<?> updateTask(@PathVariable Long id, @RequestBody Task taskData) {
return repository.findById(id)
.map(task -> {
task.setTitle(taskData.getTitle());
task.setDescription(taskData.getDescription());
task.setCompleted(taskData.isCompleted());
repository.save(task);
return ResponseEntity.noContent().build();
}).orElse(ResponseEntity.notFound().build());
}
@DeleteMapping("/{id}")
public ResponseEntity<?> deleteTask(@PathVariable Long id) {
return repository.findById(id)
.map(task -> {
repository.delete(task);
return ResponseEntity.noContent().build();
}).orElse(ResponseEntity.notFound().build());
}
}
The controller in a Spring Boot application handles incoming HTTP requests and maps them to the appropriate service or repository methods. Annotated with
@RestController
, it defines the API endpoints using annotations like@GetMapping
,@PostMapping
,@PutMapping
, and@DeleteMapping
. Controllers act as the entry point for your application’s business logic, managing the flow of data between the client and the backend. Each method in the controller typically returns a response entity or data object that is automatically serialized to JSON.

Step 6: Configure the Application
Update src/main/resources/application.properties
:
spring.datasource.url=jdbc:h2:mem:taskdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=true
Step 7: Run Your Application
From terminal:
./mvnw spring-boot:run
Or via your IDE:

Then import this collection in Postman to test your API:
{
"info": {
"name": "Task Manager API",
"schema": "<https://schema.getpostman.com/json/collection/v2.1.0/collection.json>",
"_postman_id": "abcd1234-ef56-7890-abcd-1234567890ab"
},
"item": [
{
"name": "Get All Tasks",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "<http://localhost:8080/api/tasks>",
"protocol": "http",
"host": ["localhost"],
"port": "8080",
"path": ["api", "tasks"]
}
}
},
{
"name": "Create Task",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\\n \\"title\\": \\"Write blog post\\",\\n \\"description\\": \\"Create a Spring Boot tutorial\\",\\n \\"completed\\": false\\n}"
},
"url": {
"raw": "<http://localhost:8080/api/tasks>",
"protocol": "http",
"host": ["localhost"],
"port": "8080",
"path": ["api", "tasks"]
}
}
},
{
"name": "Update Task",
"request": {
"method": "PUT",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\\n \\"title\\": \\"Updated title\\",\\n \\"description\\": \\"Updated description\\",\\n \\"completed\\": true\\n}"
},
"url": {
"raw": "<http://localhost:8080/api/tasks/1>",
"protocol": "http",
"host": ["localhost"],
"port": "8080",
"path": ["api", "tasks", "1"]
}
}
},
{
"name": "Delete Task",
"request": {
"method": "DELETE",
"header": [],
"url": {
"raw": "<http://localhost:8080/api/tasks/1>",
"protocol": "http",
"host": ["localhost"],
"port": "8080",
"path": ["api", "tasks", "1"]
}
}
}
]
}

Final Thoughts
You’ve now built a real-world CRUD API with Spring Boot and H2. In under 30 minutes, you’ve seen the power of auto-configuration, embedded servers, and clean code organization that Spring Boot brings to Java development.
What’s Next?
- Add validation using
@Valid
- Use PostgreSQL instead of H2
- Add a service layer
- Secure your API with Spring Security
Spring Boot is just the beginning of modern Java backend development. With this foundation, you can scale into microservices, integrate Kafka, build GraphQL endpoints, or deploy to the cloud.
▶️ Recommended watch: How to Handle Multiple Environments (dev, qa, prd) on Spring Boot applications? The BEST way!