DEV Community

Amrut
Amrut

Posted on

How I Built a Spring Boot Todo API in One Hour

Hey everyone! 👋

So last weekend I challenged myself to build a REST API from scratch as quickly as possible. I've been wanting to level up my Spring Boot skills, and what better way than a good old Todo API, right? Turned out, I got it done in about an hour—not bad!

Here's exactly how I did it, step by step. Whether you're just getting started with Spring Boot or looking for a quick refresher, this should help you get a working API up and running fast.

🚀 Step 1: Initialize the Project

First things first: head over to Spring Initializr (seriously, this tool is a lifesaver).

Here's what I chose:

  • Project: Maven
  • Language: Java
  • Spring Boot: 3.x (latest stable)
  • Dependencies:
    • Spring Web
    • Spring Data JPA
    • H2 Database

Once you've got those selected, hit generate, download the zip, and extract it. Easy!

📁 Step 2: Project Structure

Here's how I organized everything:

src/
 └── main/
      ├── java/com/example/todo/
      │     ├── TodoApplication.java
      │     ├── controller/TodoController.java
      │     ├── model/Todo.java
      │     └── repository/TodoRepository.java
      │
      └── resources/
            ├── application.properties
            └── data.sql (optional seed)
Enter fullscreen mode Exit fullscreen mode

Nothing fancy—just clean separation of concerns.

⚙️ Step 3: Configure application.properties

This is where we tell Spring Boot how to connect to our H2 in-memory database. Super simple setup:

spring.datasource.url=jdbc:h2:mem:todo_db
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=true
Enter fullscreen mode Exit fullscreen mode

The H2 console is awesome for debugging—you can actually see your database in action at http://localhost:8080/h2-console.

🗂️ Step 4: Create the Todo Entity

Time to model our data. Here's the Todo class:

package com.example.todo.model;

import jakarta.persistence.*;

@Entity
public class Todo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String title;
    private boolean completed;

    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }

    public String getTitle() { return title; }
    public void setTitle(String title) { this.title = title; }

    public boolean isCompleted() { return completed; }
    public void setCompleted(boolean completed) { this.completed = completed; }
}
Enter fullscreen mode Exit fullscreen mode

Pretty straightforward—just an ID, a title, and a completed flag. JPA handles all the database magic for us.

🔍 Step 5: Create the Repository

This is where Spring Data JPA really shines. You literally just need this:

package com.example.todo.repository;

import com.example.todo.model.Todo;
import org.springframework.data.jpa.repository.JpaRepository;

public interface TodoRepository extends JpaRepository<Todo, Long> {
}
Enter fullscreen mode Exit fullscreen mode

Yep, that's it! Spring automatically implements all the CRUD operations for you. No boilerplate code needed.

🎮 Step 6: Build the REST Controller

Now for the fun part—creating our API endpoints:

package com.example.todo.controller;

import com.example.todo.model.Todo;
import com.example.todo.repository.TodoRepository;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@RestController
@RequestMapping("/api/todos")
@CrossOrigin
public class TodoController {

    private final TodoRepository repository;

    public TodoController(TodoRepository repository) {
        this.repository = repository;
    }

    @GetMapping
    public List<Todo> getAll() {
        return repository.findAll();
    }

    @GetMapping("/{id}")
    public Todo getById(@PathVariable Long id) {
        return repository.findById(id).orElseThrow();
    }

    @PostMapping
    public Todo create(@RequestBody Todo todo) {
        return repository.save(todo);
    }

    @PutMapping("/{id}")
    public Todo update(@PathVariable Long id, @RequestBody Todo todo) {
        Todo existing = repository.findById(id).orElseThrow();
        existing.setTitle(todo.getTitle());
        existing.setCompleted(todo.isCompleted());
        return repository.save(existing);
    }

    @DeleteMapping("/{id}")
    public void delete(@PathVariable Long id) {
        repository.deleteById(id);
    }
}
Enter fullscreen mode Exit fullscreen mode

We've got all the RESTful operations covered: GET, POST, PUT, and DELETE. The @CrossOrigin annotation is there in case you want to call this from a frontend later.

🏃 Step 7: Main Application Class

This one's already generated by Spring Initializr, but here it is for completeness:

package com.example.todo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class TodoApplication {
    public static void main(String[] args) {
        SpringApplication.run(TodoApplication.class, args);
    }
}
Enter fullscreen mode Exit fullscreen mode

▶️ Step 8: Run It!

Time to see this baby in action. From your project root, run:

mvn spring-boot:run
Enter fullscreen mode Exit fullscreen mode

Your API should now be live at http://localhost:8080/api/todos!

Want to peek at the database? Hit up http://localhost:8080/h2-console and use the JDBC URL jdbc:h2:mem:todo_db.

🧪 Step 9: Test the API

Here's where you can use curl or Postman to test everything out:

Create a new todo:

curl -X POST -H "Content-Type: application/json" \
  -d '{"title":"Learn Spring Boot","completed":false}' \
  http://localhost:8080/api/todos
Enter fullscreen mode Exit fullscreen mode

Get all todos:

curl http://localhost:8080/api/todos
Enter fullscreen mode Exit fullscreen mode

Update a todo:

curl -X PUT -H "Content-Type: application/json" \
  -d '{"title":"Learn Spring Boot","completed":true}' \
  http://localhost:8080/api/todos/1
Enter fullscreen mode Exit fullscreen mode

Delete a todo:

curl -X DELETE http://localhost:8080/api/todos/1
Enter fullscreen mode Exit fullscreen mode

And that's it! You've got a fully functional REST API.

🎯 What I Learned

  1. Spring Boot is ridiculously fast for prototyping—most of the boilerplate is handled for you
  2. H2 is perfect for development—no need to set up a full database just to test things out
  3. JPA repositories are magical—seriously, that one-line interface saves so much time

🔮 What's Next?

This is just the foundation. From here, you could:

  • Add validation with @Valid and Bean Validation
  • Implement exception handling with @ControllerAdvice
  • Add security with Spring Security
  • Switch to a production database like PostgreSQL or MySQL
  • Write unit and integration tests

💭 Final Thoughts

Building this took me about an hour, and honestly, most of that was me making sure I had clean, readable code. If you're just learning Spring Boot, don't get overwhelmed by all the "enterprise" talk—start with something simple like this, get it working, and build from there.

What do you think? Have you built something similar? Any tips or improvements you'd suggest? Drop a comment below—I'd love to hear your thoughts! 🚀

Happy coding! ✨

Top comments (0)