Today we are going to make a REST API with Spring-data, Spring-mvc, H2 and Lombok.

First we create our classes needed for interaction with the database. The Product class and the ProductRepository interface.

public class Product{

    private Long id;

    private String name;

    private double price;

    public Product(String name, double price) {
        this.name = name;
        this.price = price;

    protected Product() {}
public interface ProductRepository extends CrudRepository{


These for now the only thing we need to know is that when we use create the ProductRepository we can manage instances of the Product class. We went more in detail over these classes in this blog post.

Now that we have our interaction with the database we can start to think how our urls should look like. There is a convention for the writing of urls.

  • URLs should include nouns, not verbs.
  • Use plural nouns only for consistency (no singular nouns).
  • Use HTTP methods (HTTP/1.1) to operate on these resources:
  • Use HTTP response status codes to represent the outcome of operations on resources.

This information comes from the the following helpful site. Now we can define our URL formats.

what it does HTTP verb URL format
get all products GET /products
get one product with id GET /products/id
create one product POST /products
update one product with id PUT /products/id
remove one product with id DELETE /products/id

Let’s start by creating the REST controller for our actions.

public class ProductRestController {

    private final ProductRepository productRepository;

    public ProductRestController(ProductRepository productRepository) {
        this.productRepository = productRepository;
  • @RestController makes the controller return JSON responses
  • @RequestMapping makes sure all requests start with /products this keeps our code DRY (don’t repeat yourself)
  • We inject our repository with constructor injection (a nice discussion about setter vs constructor injection)

Now we can create our methods in the controller. For some reason I can’t get the code working nice inside the blog so that’s why there is a link to a Github gist. We go to the methods one by one.


We use @GetMapping without any parameters, because of the @RequestMapping at the class level. When there are no products we get an empty iterable.


@PathVariable maps the {id} to id in the parameters. We check of a product exists with that id. if it does we return it with status HTTP status ok which is number 200. Otherwise we return a message and HTTP status not found which is number 404.


We can use @PostMapping with out any parameters for the same reason as with getProducts. Because one uses the GET method and the other POST method they don’t interfere with each other. @RequestBody casts the JSON body we in the request to a Product object. We save the object and return it (there is no check for when the parameters fail to map correctly).


This method combines all the annotations we learned in the last 2 methods and uses the HTTP PUT method. Again there is no check of the @RequestBody can be a Product. Because there is no method to update an existing Product we get the Product from the database and update all the attributes except the primary key and save it to the database. This is basically what an update does too. In an real application it might a nice idea to make an update method in a concrete implementation of the ProductRepository.


Works the same way as update, but now we delete the product.

This all we need to create a CRUD API in Spring.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s