Skip to main content

Command Palette

Search for a command to run...

Creating a Simple CRUD API with an In-Memory Database Using Spring Boot

A Step-by-Step Guide to Setting Up Project with Spring Initializr and Creating a CRUD API Using Spring Boot and H2 Database in Visual Studio Code

Published
7 min read
H

"Tech Enthusiast by Day, Powerlifter and Fitness Coach by Night—Bridging the Gap Between Code and Strength."

Passionate about pushing boundaries in both technology and fitness, I combine my love for coding with the discipline of powerlifting. Join me as I explore the intersections of tech innovation and physical prowess.

Welcome to Day 2 of our 30-day Java Backend Development series! Today, we'll dive into creating a simple CRUD (Create, Read, Update, Delete) API using Spring Boot with an in-memory database. We’ll be using the Spring Initializr Java Support extension in Visual Studio Code to set up our project.

Prerequisites

Make sure you have the following installed:

  • Java Development Kit (JDK 17)

  • Visual Studio Code (VS Code) with the following extensions:

    • Java Extension Pack by Microsoft

    • Spring Boot Extension Pack by Pivotal

    • Spring Initializr Java Support

Introduction to CRUD Operations

CRUD stands for Create, Read, Update, and Delete. These are the four basic operations that can be performed on data in a database. In the context of a RESTful API:

  • Create: Adding a new record to the database.

  • Read: Retrieving one or more records from the database.

  • Update: Modifying an existing record in the database.

  • Delete: Removing a record from the database.

In this tutorial, we'll build a simple API that allows you to manage a list of products. Each product will have a unique ID, name, and price, and we'll implement endpoints to perform all CRUD operations on this data.

Understanding the Dependencies

Before we begin, let's understand the key dependencies we'll be using in this project:

1. Spring Web

  • Purpose: Spring Web provides the tools needed to create RESTful web services and web applications. It includes support for handling HTTP requests, responses, and the ability to map requests to specific methods in your controllers.

  • Usage: We’ll use Spring Web to define our RESTful endpoints that allow clients to interact with our API via HTTP methods (GET, POST, PUT, DELETE).

2. Spring Data JPA

  • Purpose: Spring Data JPA simplifies the implementation of data access layers by providing a repository abstraction over the JPA (Java Persistence API). It includes built-in support for common data operations and eliminates the need for boilerplate code.

  • Usage: We'll use Spring Data JPA to interact with our in-memory database, allowing us to easily perform CRUD operations on our Product entity.

3. H2 Database (In-Memory Database)

  • Purpose: H2 is a lightweight and fast relational database that can run in memory. It's an excellent choice for development, testing, or small applications where you don't need a persistent database.

  • Usage: In this tutorial, H2 will act as our in-memory database, meaning all data will be stored temporarily while the application is running and cleared when the application stops.

Step 1: Setting Up the Project with Spring Initializr Java Support

1.1 Install the Spring Initializr Java Support Extension

Before we start, ensure you have the Spring Initializr Java Support extension installed in VS Code.

  1. Open Visual Studio Code.

  2. Go to Extensions (Ctrl+Shift+X) and search for Spring Initializr Java Support.

  3. Install the Extension.

1.2 Create a New Spring Boot Project

  1. Open the Command Palette (Ctrl+Shift+P) and type Spring Initializr: Generate a Maven Project.

  2. Select Project Parameters:

    • Group Id: com.techsights

    • Artifact Id: simple_crud

    • Name: SimpleCRUD

    • Package Name: com.techsights.simplecrud

    • Dependencies: Add the following:

      • Spring Web

      • Spring Data JPA

      • H2 Database (for in-memory database)

  3. Choose the Project Directory where you want to save your project.

Leave enough space here for a screenshot showing the configuration settings.

  1. Click 'Generate' to create the project.

1.3 Open the Project in Visual Studio Code

  1. Once the project is generated, open the project in VS Code.

  2. Wait for the dependencies to be resolved by Maven.

Leave enough space here for a screenshot showing the project structure in VS Code.

Step 2: Creating the CRUD API

2.1 Define the Entity Class

  1. Create a new package under src/main/java/com/techsights/simplecrud named model.

  2. Create a Java class inside the model package named Product.java.

package com.techsights.simplecrud.model;

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

// The @Entity annotation indicates that this class is a JPA entity.
// JPA will map this class to a table named 'Product' in the database.
@Entity
public class Product {

    // The @Id annotation marks the field 'id' as the primary key.
    // The @GeneratedValue annotation indicates that the ID should be generated automatically.
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private double price;

    // Default constructor for JPA
    public Product() {
    }

    // Parameterized constructor for easier object creation
    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }

    // Getters and setters for accessing and modifying the fields
    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

2.2 Create the Repository Interface

  1. Create a new package named repository.

  2. Create an interface ProductRepository.java in the repository package.

package com.techsights.simple_crud.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.techsights.simple_crud.model.Product;

// The @Repository annotation indicates that this interface is a Spring Data repository.
// Spring Data repositories simplify data access by providing a set of standard CRUD methods
// without the need for boilerplate code. This interface extends JpaRepository, 
// which provides JPA-specific operations, such as saving, finding, deleting entities, 
// and also includes pagination and sorting capabilities.
// The JpaRepository<T, ID> interface requires two type parameters:
// - T: The type of the entity that the repository manages (in this case, Product).
// - ID: The type of the entity's primary key (in this case, Long).
// It provides CRUD operations for the Product entity.
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
}

2.3 Implement the Service Layer

  1. Create a new package named service.

  2. Create a class ProductService.java in the service package.

package com.techsights.simple_crud.service;

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.techsights.simple_crud.model.Product;
import com.techsights.simple_crud.repository.ProductRepository;

// The @Service annotation indicates that this class is a service component in the Spring context.
// It contains business logic for managing products.
@Service
public class ProductService {

    private final ProductRepository productRepository;

    // The @Autowired annotation is used to inject the ProductRepository dependency into this service.
    @Autowired
    public ProductService(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }

    // Method to create or save a product
    public Product saveProduct(Product product) {
        return productRepository.save(product);
    }

    // Method to retrieve all products
    public List<Product> getAllProducts() {
        return productRepository.findAll();
    }

    // Method to retrieve a product by ID
    public Optional<Product> getProductById(Long id) {
        return productRepository.findById(id);
    }

    // Method to delete a product by ID
    public void deleteProduct(Long id) {
        productRepository.deleteById(id);
    }
}

2.4 Create the Controller Class

  1. Create a new package named controller.

  2. Create a class ProductController.java in the controller package.

package com.techsights.simple_crud.controller;

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.techsights.simple_crud.model.Product;
import com.techsights.simple_crud.service.ProductService;

// The @RestController annotation indicates that this class is a Spring MVC controller
// where each method returns a domain object instead of a view.
@RestController
@RequestMapping("/api/products")
public class ProductController {

    private final ProductService productService;

    // The @Autowired annotation is used to inject the ProductService dependency into this controller.
    @Autowired
    public ProductController(ProductService productService) {
        this.productService = productService;
    }

    // Method to handle HTTP POST requests for creating a new product
    @PostMapping
    public Product createProduct(@RequestBody Product product) {
        return productService.saveProduct(product);
    }

    // Method to handle HTTP GET requests for retrieving all products
    @GetMapping
    public List<Product> getAllProducts() {
        return productService.getAllProducts();
    }

    // Method to handle HTTP GET requests for retrieving a product by ID
    @GetMapping("/{id}")
    public Optional<Product> getProductById(@PathVariable Long id) {
        return productService.getProductById(id);
    }

    // Method to handle HTTP DELETE requests for deleting a product by ID
    @DeleteMapping("/{id}")
    public void deleteProduct(@PathVariable Long id) {
        productService.deleteProduct(id);
    }
}

2.5 Running the Application

  1. Run the application by opening the Command Palette (Ctrl+Shift+P) and typing Spring Boot: Run.

  2. Test the API using tools like Postman or cURL.

  • POST request to create a product:
curl -X POST -H "Content-Type: application/json" -d '{"name": "Product1", "price": 100}' http://localhost:8080/api/products
  • GET request to retrieve all products:
curl -X GET http://localhost:8080/api/products
  • GET request to retrieve a product by ID:
curl -X GET http://localhost:8080/api/products/1
  • PUT request to update a product by ID:

      curl -X PUT -H "Content-Type: application/json" -d '{"name": "Updated Product", "price": 150}' http://localhost:8080/api/products/1
    
  • DELETE request to delete a product by ID:

curl -X DELETE http://localhost:8080/api/products/1

Step 3: Committing and Pushing Code to GitHub

  1. Create a GitHub repository named simple-crud.

  2. Commit and push your code to GitHub.

     git init
     git add .
     git commit -m "Initial commit - Simple CRUD API"
     git remote add origin https://github.com/your-username/simple-crud.git
     git push -u origin main
    

    The code shown in this repository is pushed in https://github.com/hsharma1528/simple-crud.git

  3. Conclusion

    Congratulations! You’ve successfully created a simple CRUD API using Spring Boot with an in-memory H2 database. This API allows you to create, read, update, and delete products, laying the foundation for more complex applications. In the next tutorial, we’ll explore adding authentication and authorization to our API.

    Additional Resources

Stay tuned for more in this series as we continue to build on this foundation!

30 Days of Java Backend Development

Part 2 of 2

Join us on a 30-day journey to master Java backend development, from basic REST APIs to advanced concepts like microservices and reactive programming. Build a solid foundation in Java technologies

Start from the beginning

Building Your First REST API with Spring Boot

Kickstart your journey into Java backend development