Your first Spring boot RESTful API

In this tutorial, we are going to work you through the steps of building a small but functional spring boot RESTful API to perform basic CRUD operation on an Object call Item.

Your pom.xml file should have these dependencies

/itemApi/pom.xml

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

Create the Item Entity Class. You can use Lombok to auto generate Getter and Setter at compile time

itemApi/src/main/java/com/eddytnk/itemApi/model/Item.java

package com.eddytnk.itemApi.model;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
@Data
public class Item {

    @Id
    private Long id;
    private String name;
    private double price;
    private int quantity;
}

Create a JPA Repository to help manage CRUD and basic operations for this Entity. In this project, we are using H2 in-memory database. Most-likely in your project you would be using a different Database like Oracle or MySql or DB2 but however, the process is the same and spring boot will auto configure connection to the database once we add the dependency to the class path. For example one spring boot sees com.h2database in the class path it will auto-configure H2 in-memory database

itemApi/src/main/java/com/eddytnk/itemApi/repository/ItemRepository.java

package com.eddytnk.itemApi.repository;

import com.eddytnk.itemApi.model.Item;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ItemRepository extends JpaRepository<Item, Long> {
}

Now that you have created the Entity class and a Repository to manage persistent and retrieval of this entity, you will now need the Service class to manage the business logic around this entity.

package com.eddytnk.itemApi.service;

import com.eddytnk.itemApi.model.Item;
import com.eddytnk.itemApi.repository.ItemRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service
public class ItemService {

    private ItemRepository itemRepository;

    @Autowired
    public ItemService(ItemRepository itemRepository) {
        this.itemRepository = itemRepository;
    }

    public List<Item> getAllItems() {
        return itemRepository.findAll();
    }

    public Item getItem(Long id) {
        Optional<Item> itemOptional = itemRepository.findById(id);
        if (!itemOptional.isPresent()) {
            throw new RuntimeException("Item not found.");
        }
        return itemOptional.get();
    }

    public Item addNewItem(Item item) {
        return itemRepository.save(item);
    }

    public void updateItem(Long id, Item item) {
        Optional<Item> itemOptional = itemRepository.findById(id);
        if (!itemOptional.isPresent()) {
            throw new RuntimeException("Item not found.");
        }
        Item newItem = itemOptional.get();
        newItem.setId(item.getId());
        newItem.setName(item.getName());
        newItem.setPrice(item.getPrice());
        newItem.setQuantity(item.getQuantity());
        itemRepository.save(newItem);
    }

    public void removeItem(Long id) {
        itemRepository.deleteById(id);
    }
}

Every API is not complete without the Interface in which the user connects to the API. This interface is defined in the Controller Component.

package com.eddytnk.itemApi.controller;

import com.eddytnk.itemApi.model.Item;
import com.eddytnk.itemApi.service.ItemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.net.URI;
import java.util.List;

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

    private ItemService itemService;

    @Autowired
    public ItemController(ItemService itemService) {
        this.itemService = itemService;
    }

    @PutMapping("/items")
    public ResponseEntity<?> addItem(@RequestBody Item item) {
        Item savedItem = itemService.addNewItem(item);
        return ResponseEntity.created(URI.create("/items/" + savedItem.getId())).build();
    }

    @GetMapping("/items")
    public ResponseEntity<List<Item>> getItems() {
        return ResponseEntity.ok(itemService.getAllItems());
    }

    @GetMapping("/items/{itemId}")
    public ResponseEntity<Item> getItem(@PathVariable("itemId") Long id) {
        return ResponseEntity.ok(itemService.getItem(id));
    }

    @PostMapping("/items/{itemId}")
    public ResponseEntity<?> updateItem(@PathVariable("itemId") Long id, @RequestBody Item item) {
        itemService.updateItem(id, item);
        return ResponseEntity.noContent().build();
    }

    @DeleteMapping("/items/{itemId}")
    public ResponseEntity<?> deleteItem(@PathVariable("itemId") Long id) {
        itemService.removeItem(id);
        return ResponseEntity.noContent().build();
    }

}

You can now run your application and try out the different endpoints

GET /api/items –> Retrieve all Items

GET /api/items/{itemId} –> retrieve a particular Item

PUT /api/Items/ –> Add a new Item to the Database

POST /api/items/{itemId} –> Update the Item with id {itemId}

DELETE /api/items/{itemId} –> Delete item with id {itemId}

When developing RESTful API, we have to make sure we properly use all the HTTP verbs GET, POST, PUT, DELETE, PATCH correctly

The HTTP Verb PATCH is mostly used when a particular field in the Entity is to be modified independently from the others e.g if i want to only change the value of price in the Item Entity while keeping all the others unchanged

@PatchMapping("/items/{itemId}")
    public ResponseEntity<?> changePrice(@PathVariable("itemId") Long id, @RequestParam("price") Double price) {
        itemService.changePrice(id, price);
        return ResponseEntity.noContent().build();
    }

Download or Clone source code on GitHub

2 Comments
  1. Ngouleu Tertullien
  2. Buy CBD

Leave a Reply

Your email address will not be published.