The key difference between RESTful Web service and traditional MVC pattern is the way content returned to the client. The traditional MVC pattern development will directly return a view to the client, but RESTful Web service will generally return the returned data as JSON. This is the so-called front-end and back-end separation development.

In this post, we will show how to build another RESTful Web Service with Spring Boot.

Here is a more simple demo about How to Building A RESTful Web Service with Spring Boot?

Content Overview

In the following content, you will learn the following things:

  • Lombok optimization code tool
  • @RestController
  • @RequestParam and @Pathvairable
  • @RequestMapping, @GetMapping……
  • Responsity

Lombok – Code optimizer tool

Because this development uses Lombok, a tool that simplifies Java code, we need to add related dependencies in pom.xml. The pom.xml like that:

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.etbye</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>13</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-starter-data-rest</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Entity class

Suppose we have a bookshelf with many books on it.  We will create a new Bookentity class.

package com.etbye.restservice;

import lombok.Data;

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

@Data
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    private String name;
    private String author;

}

For using the Lombok dependency in pom.xml, we no need to write setter and getter for the fields, these jobs are done by Lombok.

Controller

To add, find and view the books on the bookshelf, we need to write a controller to perform those tasks. To do this, we create a new class BookController

package com.etbye.restservice;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

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

    private List<Book> books = new ArrayList<>();

    //add new book to the bookshelf
    @PostMapping("/book")
    public ResponseEntity<List<Book>> addBook(@RequestBody Book book) {
        books.add(book);
        return ResponseEntity.ok(books);
    }

    //delete the book by id
    @DeleteMapping("/book/{id}")
    public ResponseEntity deleteBookById(@PathVariable("id") int id) {
        books.removeIf(book -> book.getId() == id);
        return ResponseEntity.ok(books);
    }

    //update a book, if the book no exists, then add it.
    @PutMapping("/book/{id}")
    public Book updateBookById(@RequestBody Book newbook, 
           @PathVariable("id") int id) {
        for (Book book: books) {
            if (book.getId() == id) {
                book.setName(newbook.getName());
                book.setAuthor(newbook.getAuthor());
                return book;
            }
        }
        books.add(newbook);
        return newbook;
    }

    //get all books info
    @GetMapping("/book")
    public ResponseEntity<List<Book>> getBooks() {
        return ResponseEntity.ok(books);
    }

    //find books by name
    @GetMapping("/book/{name}")
    public ResponseEntity getBookByName(@RequestParam("name") String name) {
        List<Book> results = books.stream().filter(book -> book.getName().equals(name)).collect(Collectors.toList());
        return ResponseEntity.ok(results);
    }
}
  • @RestController Write the returned object data directly to the HTTP response in JSON or XML. In most cases, it is returned directly to the client as JSON, and in rare cases, it is returned as XML. As wen mentioned in How to Building A RESTful Web Service with Spring Boot , @RestController is the shorthand of @Controllerand @RestController.
  • @RequestMapping: GET and PUT, POST, etc. are not specified in the above example, because @RequestMappingmapped all HTTP Actions by default. you can use @RequestMapping(method=ActionType)to narrow down this mapping.
  • @PostMappingActually equivalent to @RequestMapping(method = RequestMethod.POST), it’s the same to @DeleteMapping@GetMapping.
  • @PathVariable: Take the parameters in the URL address.  @RequestParamThe query parameter value of the URL.
  • @RequestBody: Deserialized the JSON body type data in the HttpRequest body into Java object type.
  • ResponseEntity: Represents the entire HTTP Response: status code, header, and body content. We can use it to customize the content of the HTTP Response.

Run the project

To add data (POST)

http://localhost:8080/api/book

First, we can use the Postman API app to add(post) a few books info. Of course, you can also use the Test TESTful web service plugin on IDEA, or using the curl command in terminal to do that.

To delete book by id (DELETE)

http://localhost:8080/api/book/3 (delete the book which id=3)

To view all books (GET)

http://localhost:8080/api/book/ (get all the book info)

Get the book by name (GET)

http://localhost:8080/api/book/name/?name=bookName

Summary

In this article, we learned to use Lombok to optimize the Java code, as well as some developing common RestFul Web Service annotations:

@RestController , @RequestMapping@PostMapping@PathVariable,  @RequestParam@RequestBodyand HTTP Response and related Responsityclasses.