π Introduction
Spring Boot makes it easy to create production-ready REST APIs with minimal setup. In this guide, weβll walk you through building a simple REST API with Java 21 and Spring Boot using:
- Java 21 (LTS)
- Spring Boot 3+
- Maven
- IntelliJ IDEA or any IDE of your choice
Our API will manage a list of books with basic CRUD operations.
π Project Structure

ποΈ Step-by-Step Implementation
1. Create the Spring Boot Project
Use Spring Initializr with the following:
- Project: Maven
- Language: Java
- Spring Boot: 3.2+
- Dependencies: Spring Web, Spring Boot DevTools
2. pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.kscodes</groupId> <artifactId>book-api</artifactId> <version>1.0.0</version> <name>Book API</name> <properties> <java.version>21</java.version> </properties> <dependencies> <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> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> |
3. Main Class β BookApiApplication.java
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.kscodes.bookapi; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class BookApiApplication { public static void main(String[] args) { SpringApplication.run(BookApiApplication.class, args); } } |
4. Model β Book.java
1 2 3 4 5 |
package com.kscodes.bookapi.model; public record Book(Long id, String title, String author) {} |
Weβre using Java 21βs
record
class to keep the model concise and immutable.
5. Service β BookService.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
package com.kscodes.bookapi.service; import com.kscodes.bookapi.model.Book; import org.springframework.stereotype.Service; import java.util.*; @Service public class BookService { private final Map<Long, Book> books = new HashMap<>(); private long currentId = 1; public List<Book> getAllBooks() { return new ArrayList<>(books.values()); } public Book getBookById(Long id) { return books.get(id); } public Book addBook(Book book) { Book newBook = new Book(currentId++, book.title(), book.author()); books.put(newBook.id(), newBook); return newBook; } public Book updateBook(Long id, Book updatedBook) { if (!books.containsKey(id)) return null; Book newBook = new Book(id, updatedBook.title(), updatedBook.author()); books.put(id, newBook); return newBook; } public boolean deleteBook(Long id) { return books.remove(id) != null; } } |
6. Controller β BookController.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
package com.kscodes.bookapi.controller; import com.kscodes.bookapi.model.Book; import com.kscodes.bookapi.service.BookService; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/api/books") public class BookController { private final BookService service; public BookController(BookService service) { this.service = service; } @GetMapping public List<Book> getAllBooks() { return service.getAllBooks(); } @GetMapping("/{id}") public Book getBook(@PathVariable Long id) { return service.getBookById(id); } @PostMapping public Book createBook(@RequestBody Book book) { return service.addBook(book); } @PutMapping("/{id}") public Book updateBook(@PathVariable Long id, @RequestBody Book book) { return service.updateBook(id, book); } @DeleteMapping("/{id}") public void deleteBook(@PathVariable Long id) { service.deleteBook(id); } } |
7. application.properties
1 2 3 |
server.port=8080 |
π§ͺ Test Your API
Use Postman or curl to interact with the following endpoints:
GET /api/books
β List all booksGET /api/books/{id}
β Get a book by IDPOST /api/books
β Create a new bookPUT /api/books/{id}
β Update bookDELETE /api/books/{id}
β Delete book
β Summary
Youβve just built a simple yet functional REST API with Java 21 and Spring Boot. We used record
, REST annotations, and an in-memory service to manage book data.
You can download the complete source code here