Coding a Spring Boot Microservice

To create a Weather Microservice with Spring Boot providing the actual temperature by means of a RESTFul endpoint, the following steps are necessary:

  1. Create an application entry point to explicitly start the Spring Boot application.
  2. Perform a basic configuration of the application.
  3. Create a RESTful resource-controller class.

In the example, all classes belong to a com.packtpub.microservices.weatherservice package. In Maven's project structure, the package belongs to {project-root}/src/main/java folder. When a Java IDE is used, packages are automatically put in this folder.

Spring Boot applications require an explicit entry point in the form of the public static void main() method, as any Java application does. In this main() method, the Spring Boot application is started and configured. The beginning of a Spring Boot project is very similar to creating a Java SE application:

package com.packpub.microservices.weatherservice;

public class WeatherServiceApplication {
public static void main(String[] args) {
//Start & configure Spring Boot application
}
}

The next step is to turn a common Java SE application into a Spring-Framework-enabled Java application. Spring Boot is a very convenient tool for doing that. The SpringApplication class from the org.springframework.boot package instantiates the Spring Framework. Its public static method, run(...), takes care of everything required. The run() method is overloaded multiple times. A simple variant covering most use cases is invoked in the SpringApplication.run(Object[] sources, String... args) version. The very first argument is the Class object of the Spring Boot application configuration. This points to a class holding the Spring Boot application configuration and there can be multiple such classes in a project if required. For the example project, the configuration class is the WeatherServiceApplication class, which by no coincidence also hosts the main() method. It is a common practice to unite the Spring Boot configuration class with a class hosting the main() method, even though it is not necessary.

As already mentioned, a Spring Framework application needs to be configured. With Spring Boot, the whole framework has evolved into a convention-over-configuration approach. This means a reasonable default configuration, with changes made only to the parts as necessary. Most of the times, there are no changes at all. The default configuration comes with a SpringBootApplication annotation from the org.springframework.boot.autoconfigure package. By applying it to the WeatherServiceApplication configuration class, the Spring Boot Microservice startup procedure is defined and complete:

package com.packpub.microservices.weather;

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

@SpringBootApplication
public class WeatherServiceApplication {

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

From the example, it can be observed that the array of String arguments is a purely optional argument. Only the Class object of the WeatherServiceApplication configuration class is passed as an argument to the SpringApplication.run() method. The @SpringBootApplication configuration annotation represents a union of classical Spring Framework annotations:

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

@SpringBootConfiguration helps Spring Boot to identify the annotated class as a configuration class. The remaining two annotations, @EnableAutoConfiguration and @ComponentScan, affect the behavior of Spring Dependency Injection and the bean-configuration mechanisms present inside a Spring application. This makes Spring Framework discover all possible beans on the classpath and attempt to resolve the dependency-injection tree automatically, without manually adding each and every bean. 

With Spring Boot Microservice configured, the Weather Microservice functionality can be straightforwardly implemented. The Weather Microservice is going to provide one simple endpoint that returns an average temperature in the whole city. The service contract, that is, the method returning the temperature, promises to provide the temperature value. The service supports two scales, namely CELSIUS and FAHRENHEIT. This is the whole domain model of the Microservice. The package chosen for the entire domain model in the following examples is com.packpub.microservices.weather.domain, the same package as the Spring Boot main and configuration class.

There is one enumeration to be created, representing the temperature scales available. For simplicity, the CELSIUS and FAHRENHEIT scales are used. The enumeration is named TemperatureScale:

package com.packtpub.microservices.weather.domain;
public enum TemperatureScale {
CELSIUS, FAHRENHEIT
}

Afterward, an object representation of the temperature itself, named the Tempterature class, is created:

package com.packpub.microservices.weather.domain;

public class Temperature {

private Double temperature;
private TemperatureScale temperatureScale;

public Double getTemperature() {
return temperature;
}

public void setTemperature(Double temperature) {
this.temperature = temperature;
}

public TemperatureScale getTemperatureScale() {
return temperatureScale;
}

public void setTemperatureScale(TemperatureScale temperatureScale) {
this.temperatureScale = temperatureScale;
}
}

With the Object representation of the Microservice's domain model sealed, the structure of the average temperature resource is known and all the necessities for a successful average-temperature resource implementation are completed. The spring Framework leverages the functionality of the Spring REST MVC to enable developers to create RESTful services. An average temperature resource requires a new class placed in a com.packpub.microservices.weather package, named TemperatureResource. The TemperatureResource class hosts one method, named getAverageTemperature(), with a return type of ResponseEntity<T> from the org.springframework.http package:

package com.packpub.microservices.weather.domain;

import com.packtpub.microservices.domain.weather.Temperature;
import com.packtpub.microservices.domain.weather.TemperatureScale;
import org.springframework.http.ResponseEntity;

public class TemperatureResource {

public ResponseEntity<Temperature> getAverageTemperature() {
// Not yet implemented in this step
}
}

The ResponseEntity class has one generic parameter, T, defined. This generic parameter represents the type of the Java object serialized in the HTTP response body. For the average-temperature resource, the type is Temperature. In other words, if there are no errors during the getAverageTemperature() method invocation, an instance of ResponseEntity containing the Temperature class object is set. The HTTP 200 OK status code is set for ResponseEntity. Fulfilling this contract instantiates the Temperature object, sets its properties, and returns it wrapped by a ResponseEntity object:

package com.packpub.microservices.weather;

import com.packtpub.microservices.domain.weather.Temperature;
import com.packtpub.microservices.domain.weather.TemperatureScale;
import org.springframework.http.ResponseEntity;

public class TemperatureResource {

public ResponseEntity<Temperature> getAverageTemperature() {
Temperature temperature = new Temperature();
temperature.setTemperature(35D);
temperature.setTemperatureScale(TemperatureScale.CELSIUS);

return ResponseEntity.ok(temperature);
}
}

The instantiation of the Temperature object, and the setting of its properties, are parts of a standard Java code. The created Temperature instance is wrapped by ResponseEntity with the ResponseEntity.ok(temperature) method. This entry tells Spring to return an HTTP response with HTTP status 200 OK and serialize an instance of Temperature in the method body. In fact, it is a convenient shortcut for ResponseEntity.status(HttpStatus.OK).body(temperature). ResponseEntity follows a very common builder pattern, making it easy and quick to configure the response. 

The Microservice functionality is defined; however, there is no way for Spring Framework to recognize, under which URL the temperature resource is available. First, Spring has to be told that the TemperatureResource class is a RESTful controller by using the @RestController annotation. A rest controller is an internal naming related only to the Spring Framework, marking a class as a web controller and marking a method's return value as serialized in the HTTP response body.

The origin of this annotation can be found in Spring MVC, a mature Spring component supporting the famous Model-View-Controller pattern. Spring REST MVC builds on top of this historical functionality. In reality, @RestController combines two older annotations: @Controller and @ResponseBody

The basic context path of all endpoints regarding the temperature resource should be "/temperature". To achieve this, a @RequestMapping annotation from the org.springframework.web.bind.annotation package may be used. The average temperature endpoint is available via the HTTP GET method, as defined in RFC 2616. To define the state method, the @RequestMapping attribute is used once again, this time the method attribute is filled with the GET value from the RequestMethod enumeration, present in the same package as the @RequestMapping annotation itself:

package com.packpub.microservices.weather;

import com.packtpub.microservices.domain.weather.Temperature;
import com.packtpub.microservices.domain.weather.TemperatureScale;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(path = "/temperature")
public class TemperatureResource {

@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<Temperature> getAverageTemperature() {
Temperature temperature = new Temperature();
temperature.setTemperature(35D);
temperature.setTemperatureScale(TemperatureScale.CELSIUS);

return ResponseEntity.ok(temperature);
}
}

It should be noted that method namings are not considered in any way when Spring REST MVC assembles the final URL to the endpoint. The getAverageTemperature() method can be renamed without any impact on the RESTful interface whatsoever. With TemperatureClass being implemented and the required Spring REST MVC metadata in a form of annotations being added, the final step has been reached and the Weather Microservice implemented with Spring Boot is ready to be run.

The final outline of the project using the example package naming is demonstrated in the following filesystem tree:

.
├── main
│ ├── java
│ │ └── com
│ │ └── packpub
│ │ └── microservices
│ │ └── weather
│ │ ├── domain
│ │ │ ├── Temperature.java
│ │ │ └── TemperatureScale.java
│ │ ├── TemperatureResource.java
│ │ └── WeatherServiceApplication.java
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.15.56.12