Spring Boot: CRUD API for Beginners – Part 1

Step - 1: What is Spring Boot?

Spring Boot is the Java framework that helps you build the production ready backend applications with the minimal setup.

This framework is actually a magic, I tell you why it’s a magic:

  1. We just need to add the dependency of Spring Web and its done your spring boot application is created.

  2. Spring Web contains a Tomcat Server for running your Spring boot web application.

  3. More over it contains the spring mvc and the Json Processing libraries like Jackson.

It follows the convention over configuration approach i.e. you don’t have to write those xml file configurations to configure your project. Spring boot handles it automatically.

You just need to focus on the main Business Logic and write the working logic that runs your and power your system and the rest of configurations are handled automatically by the Spring Boot.

Isn’t this a magic that every configurations are handled automatically in background as you write your code!!

Step-2: Project Setup

Lets head to our favorite website spring initializer: Spring Initializr

Setting:

  • Project: Maven

  • Language: Java

  • Spring Boot: 3.5.4

  • Project Metadata:

    • Group: com.book-management

    • Artifact: system

    • Name: system

    • Description: Basic CRUD API on Book Management

    • Package name: com.book-management.system

    • Packaging: Jar

    • Java: 21 (21 is a LTS Version!!)

  • Dependencies:

    • Spring Web (For Rest API’s)

    • Spring Data JPA (For Database Access)

    • H2 Database (In-memory Database for Testing)

Download the Project → Unzip it → open it is IntelliJ Idea.

Wait for some minutes until IntelliJ Idea sets up the project.

Step-3: Building the Project

Head over to the following directory in your project setup: src/main/java/com/book_management/system

  • Right click on com.book_management.system and create a new Package and give it a name “model“ and press enter.

  • Now again right click on the model package and create a new Java Class and name it as “Book.java”

package com.book_management.system.model;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long bookId;

    private String name;

    private String title;

    private String author;

//    NoArgsConstructor
    public Book(){
    }

//    AllArgsConstructor
    public Book(Long bookId, String name, String title, String author) {
        this.author = author;
        this.name = name;
        this.title = title;
        this.bookId = bookId;
    }

//    GettersAndSetters
    public Long getBookId() {
        return bookId;
    }

    public void setBookId(Long bookId) {
        this.bookId = bookId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getTitle() {
        return title;
    }

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

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

}
  • Right click on com.book_management.system and create a new package and give it a name “repository” and press enter.

  • Create an Interface class names “BookRepository.java“

package com.book_management.system.repository;

import com.book_management.system.model.Book;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface BookRepository extends JpaRepository<Book, Long> {
}
  • JpaRepository gives the built in methods like:

    • findAll()

    • findById()

    • save()

    • saveAll()

    • deleteById()

    • delete()

  • Again create a package named “service“ by right clicking on com.book_management.system and create a class named “BookService“ inside the “service” package.

package com.book_management.system.service;

import com.book_management.system.model.Book;
import com.book_management.system.repository.BookRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class BookService {

    @Autowired
    private BookRepository bookRepository;

    public Book addNewBook(Book book) {

        return bookRepository.save(book);

    }

    public Book getBookById(Long bookId) {

        return bookRepository.findById(bookId)
                .orElseThrow(() -> new RuntimeException("No Book found by the bookId: " + bookId));

    }

    public List<Book> getAllBooks() {

        return bookRepository.findAll();

    }

    public Book updateBookById(Long bookId, Book updatedBook) {

        Book existingBook = bookRepository.findById(bookId)
                .orElseThrow(() -> new RuntimeException("No Book found by the bookId: " + bookId));

        existingBook.setAuthor(updatedBook.getAuthor());
        existingBook.setName(updatedBook.getName());
        existingBook.setTitle(updatedBook.getTitle());

        return bookRepository.save(existingBook);

    }

    public String deleteBookById(Long bookId) {

        Book existingBook = bookRepository.findById(bookId)
                .orElseThrow(() -> new RuntimeException("No Book found by the bookId: " + bookId));

        bookRepository.delete(existingBook);

        return "Book with bookId: " + bookId + " deleted Successfully!!";

    }

}
  • Now its turn for creating the “controller” package inside com.book_management.system and create a class named “BookController.java“ inside the “controller“ package.
package com.book_management.system.controller;

import com.book_management.system.model.Book;
import com.book_management.system.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api")
public class BookController {

    @Autowired
    private BookService bookService;

    @PostMapping("/books")
    public ResponseEntity<Book> addNewBook(@RequestBody Book book) {

        return new ResponseEntity<>(bookService.addNewBook(book), HttpStatus.CREATED);

    }

    @GetMapping("/books/bookId/{bookId}")
    public ResponseEntity<Book> getBookById(@PathVariable Long bookId) {

        return new ResponseEntity<>(bookService.getBookById(bookId), HttpStatus.FOUND);

    }

    @GetMapping("/books")
    public ResponseEntity<List<Book>> getAllBooks() {

        return new ResponseEntity<>(bookService.getAllBooks(), HttpStatus.FOUND);

    }

    @PutMapping("/books/update-book/bookId/{bookId}")
    public ResponseEntity<Book> updateBookById(@PathVariable Long bookId, @RequestBody Book book) {

        return new ResponseEntity<>(bookService.updateBookById(bookId, book), HttpStatus.OK);

    }

    @DeleteMapping("/books/bookId/{bookId}")
    public ResponseEntity<String> deleteBookById(@PathVariable Long bookId) {

        return new ResponseEntity<>(bookService.deleteBookById(bookId), HttpStatus.OK);

    }

}

Step-4: Configure H2 In-memory Database

  • Head over to the application.properties file, located in the resources folder of your project structure of book management system.

  • Inside application.properties file, add the following configurations:

spring.application.name=system

# H2-Database Configurations:
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa

# JPA-Hibernate & H2 Console Configuration
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

Step-5: Test the API with Postman

  • Head over to the SystemApplication.java file in your project structure and run SystemApplication.java file.

  • Once the Tomcat Server starts, Head over to the Postman API to test your api’s.

  • Create the following endpoints for testing your CRUD API’s in the postman:

    • Add New Book(POST): http://localhost:8080/api/books and add the given below JSON Script to add the book:

        {
          "name": "Spring Boot From Scratch",
          "title": "Spring Boot: CRUD API for Beginners",
          "author": "Harshil Champaneri"
        }
      
    • Get Book By Id(GET): http://localhost:8080/api/books/bookId/{bookId}

    • Get All Books(GET): http://localhost:8080/api/books

    • Update Book By Id(PUT): http://localhost:8080/api/books/update-book/bookId/{bookId} and add the give below JSON Script to update the book:

        {
          "name": "Spring Boot Essentials",
          "title": "Spring Boot: Build Your First CRUD API",
          "author": "Harshil Champaneri"
        }
      
    • Delete Book By Id(DELETE): http://localhost:8080/api/books/bookId/{bookId}

  • Test all this CRUD API’s in the Postman.

Step-6: Adding Validations

  • We don’t want anyone to add the new Book without any name, title and author.

  • Currently anyone can add the book without name, title and author. To Restrict user from doing so we will modify our Book.java file as attached below:

package com.book_management.system.model;

import jakarta.persistence.*;

@Entity
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long bookId;

    @Column(nullable = false, unique = true)
    private String name;

    @Column(nullable = false)
    private String title;

    @Column(nullable = false)
    private String author;

//    NoArgsConstructor
    public Book(){
    }

//    AllArgsConstructor
    public Book(Long bookId, String name, String title, String author) {
        this.author = author;
        this.name = name;
        this.title = title;
        this.bookId = bookId;
    }

//    GettersAndSetters
    public Long getBookId() {
        return bookId;
    }

    public void setBookId(Long bookId) {
        this.bookId = bookId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getTitle() {
        return title;
    }

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

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

}
  • Now the user can not add the book with empty name, title and author.

Step-7: Configuring the PostgreSQL Database Driver

  • Again head over to our favorite website: spring-initializr

  • Remove all the Previous Dependencies if present and then Click on Add Dependency.

  • Search for PostgreSQL Driver and add the Dependency.

  • Click on the Explore section and copy the following part and paste it into dependencies section of pom.xml file located in your project structure of book management system.

      <dependency>
          <groupId>org.postgresql</groupId>
          <artifactId>postgresql</artifactId>
          <scope>runtime</scope>
      </dependency>
    
  • Also comment out the dependency of H2-Database from your pom.xml file.

      <dependency>
          <groupId>com.h2database</groupId>
          <artifactId>h2</artifactId>
          <scope>runtime</scope>
      </dependency>
    
  • Reload the Maven changes after making the above mentioned changes into pom.xml file.

Step-8: Connecting with PostgreSQL Database

  • Head over to the application.properties file and make the following changes in that:
spring.application.name=system

# H2-Database Configurations:
#spring.datasource.url=jdbc:h2:mem:testdb
#spring.datasource.driver-class-name=org.h2.Driver
#spring.datasource.username=sa

# JPA-Hibernate & H2 Console Configurations:
#spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
#spring.jpa.hibernate.ddl-auto=update
#spring.h2.console.enabled=true
#spring.h2.console.path=/h2-console

# PostgreSQL Database Configurations:
spring.datasource.url=jdbc:postgresql://localhost:5432/book_management_db
spring.datasource.username=your_db_username
spring.datasource.password=your_db_password
spring.datasource.driver-class-name=org.postgresql.Driver

# JPA-Hibernate PostgreSQL Console Configurations:
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
  • Next create the database with name “book_management_db“ into your PostgreSQL Database.

  • After that replace “your_db_username” with your username in PostgreSQL Database.

  • Similarly replace “your_db_password“ with your PostgreSQL Password.

  • And Congratulations you are all set now.

  • Your Database is successfully connected with our Spring Boot application.

0
Subscribe to my newsletter

Read articles from Harshil Champaneri directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Harshil Champaneri
Harshil Champaneri

Passionate Java Full Stack Developer | Expert in Java, Spring Boot, Spring AI, Hibernate, Spring Security | Skilled in MySQL, PostgreSQL, React.js, Tailwind CSS | Core Skills: DSA, OOP, DBMS, OS