Building a RESTful Web Service


This guide walks you through the process of how to create a “Hello, World” RESTful web service with Spring Boot.

What We Will Be Building

we will be build a service that will accept HTTP GET requests at
http://localhost:8080/greeting. It will respond with a JSON representation of a greeting, as the following listing shows:

{
  "id": 1,
  "message": "Hello World!",
}

You can also customize the greeting by passing an optional name query parameter string as shown below:

http://localhost:8080/greeting?name=John

The name query parameter value would override the default value of World and would be reflected in the response, as shown below:


{
  "id": 1,
  "message": "Hello John!",
}

Prerequisite

  • Your favorite text editor or IDE
    • for this tutorial we have used the Intellij IDEA
  • Java 17 or Later
    • The java jdk can be downloaded here https://www.oracle.com/java/technologies/downloads/
  • Gradle 7.5+ or Maven 3.5+
    • both can be download here respectively 
      https://gradle.org/install/ https://maven.apache.org/download.cgi

To follow exactly this guide, I will advice you use the Intellij IDEA

Creating project with Spring Initializr

You can use the link below to get a pre-initialized project, all you have to do is click Generate to download a ZIP file. The project is already configured to fit this example tutorial.

https://start.spring.io/#!type=maven-project&groupId=com.example&artifactId=rest-service&name=rest-service&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.rest-service&dependencies=web

You can also manually initialize the project:
  1. Navigate to https://start.spring.io. This will pull in all the dependencies that you need for an application and most of the setup will be done for you.
  2. Choose either Gradle or Maven and the language you are comfortable with. In this guide we have used Maven and Java.
  3. Click Dependencies and select Spring Web
  4. Click Generate
  5. Download the resulting ZIP file

For faster setup, use the pre-initialized project above, once the ZIP file is download, Import it inside your Intellij IDEA

{{nextPage}}

Creating a Resource class

Now that we have set up the project, we can now go ahead to create the web service.

We have to first start to think about the service interactions and how they would communication with each other. The service will handle a GET request for /greeting, then it would optionally take a name query parameter. The GET request should also return a 200 OK response with JSON body which represents a greeting message. The output should look like the below:

{
  "id": 1,
  "message": "Hello World!"
}

The id field represents the unique identifier for the greeting, and message is the representation of the greeting.

To model the greeting JSON object create a resource representation class. To do this we would use the Java record class, create this Java record class in src/main/java/com/chisom/rest_service/dto/Greeting.java as show below:

  	

package com.chisom.rest_service.dto;

public record Greeting(Long id, String message) {

}

Jackson JSON (https://github.com/FasterXML/jackson) library is used by this application to automatically marshal instances of type Greeting into JSON. Jackson is included by default by the web starter dependency.

Creating The Service Resource

The service layer in Spring Boot is responsible for the business logic of the application, it serves as the bride between the controller (which is responsible for handling the HTTP requests) and the repository (which handles the database operations). Service layer helps the application becomes more modular, reusable and very easy to maintain. The components are identified by the @Service annotation, and the GreetingService shown in the following package (src/main/java/com/chisom/rest_service/service/GreetingService.java) which contains a method getGreeting that returns a new instance of the Greeting class: 


package com.chisom.rest_service.service;

import com.chisom.rest_service.dto.Greeting;
import org.springframework.stereotype.Service;

import java.util.concurrent.atomic.AtomicLong;

@Service
public class GreetingService {

    private final AtomicLong counter = new AtomicLong();
    
    public Greeting getGreeting(String name) {
        Long id = counter.incrementAndGet();
        String message = String.format("Hello, %s!", name);
        return new Greeting(id, message);
    }
}

{{nextPage}}

Creating The Controller Resource

In the Spring Boot way of building a RESTful web services, HTTP requests are handled by a controller. These components are identified by the @RestController annotation, and the GreetingController shown in the following package (src/main/java/com/chisom/rest_service/controller/GreetingController.java) handles GET requests for /greeting by returning a new instance of the Greeting class:


package com.chisom.rest_service.controller;

import com.chisom.rest_service.dto.Greeting;
import com.chisom.rest_service.service.GreetingService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

    private final GreetingService service;

    public GreetingController(GreetingService service) {
        this.service = service;
    }

    @GetMapping("/greeting")
	public ResponseEntity<Greeting> greeting(
        @RequestParam(value = "name", defaultValue = "World", required = false) String name) {
    	return new ResponseEntity<>(service.getGreeting(name), HttpStatus.OK);
	}
}

This controller is straight forward, concise and simple, but there are plenty things going on under the hood. Lets break it down step by step.

The @GetMapping annotation makes sure that HTTP GET requests to the /greeting endpoint are mapped to the greeting() method.

@RequestParam binds the value of the request query parameter name into the name parameter of the greeting() method. If the name parameter is not provided, the request defaultValue of World will be used.
The implementation of the method greeting() in  GreetingController, interacts with the service layer  getGreeting() method in class GreetingService.java which creates and returns a new Greeting object with id and message attributes based on the next value from the counter and formats the given name.

Our code uses the Spring Boot @RestController annotation, which marks the class as a controller where every method returns a domain object. 

@RestController is a shorthand for including both @Controller and @ResponseBody.
The Greeting object must be converted to JSON. Thanks to the Spring Boot HTTP message converter support, you don't need to do this conversion manually, because Jackson 2 is in the classpath, and Spring’s MappingJackson2HttpMessageConverter is automatically chosen to convert the Greeting object instance to JSON as we will see later 
below.


How To Run The Application

Spring Initializr creates an application class for you automatically, you do not need to further add any modification to the class. The following package (src/main/java/com/chisom/rest_service/RestServiceApplication.java) shows the application class:

package com.chisom.rest_service;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class RestServiceApplication {

	public static void main(String[] args) {
		SpringApplication.run(RestServiceApplication.class, args);
	}

}


The @SpringBootApplication is a power annotation that adds all of the following annotations:

  • @Configuration: Marks the class as a bean definitions for the application context.
  • @EnableAutoConfiguration: Instructs Spring Boot to start configuring/adding beans based on classpath settings, other beans, and various property settings. Lets say for example the spring-webmvc is on the classpath, this annotation marks the application as a web application and activates key behaviors, such as setting up a DispatcherServlet.
  • @ComponentScan: Instructs Spring to look for other components, configurations, and services in the com/chisom package, letting it find the controllers.

The main() method uses Spring Boot’s SpringApplication.run() method to launch an application. 

if you are using Maven you can run the application with the command in you terminal
./mvnw spring-boot:run. Make sure you are in the project directory.
If you are using Gradle, you can run the applicatio with the command in your terminal
./gradlew bootRun. Make sure you are in the project directory

Alternatively you can run the application by clicking on the run button as shown in the image below