, ,

Spring Framework 5 introduces WebClient, a component in the new Web Reactive framework to build Web applications that are reactive and non-blocking.

In web applications, a common requirement is to make HTTP calls to other services.

Prior to Spring 5, there was RestTemplate for client-side HTTP access. RestTemplate, which is part of the Spring MVC project, enables communication with HTTP servers and enforces RESTful principles.

Other options to perform HTTP operations from Spring Boot applications include the Apache HttpClient library. These options are based upon the Java Servlet API, which is blocking (aka not reactive).

With Spring Framework 5, you now have a new reactive WebClient that provides a higher level, common API over HTTP client libraries.

This post assumes you have basic knowledge of Spring 5 Reactive Programming.

If you are new to reactive programming, checkout my course, Spring Framework 5: Beginner to Guru which covers reactive programming with Spring Framework 5.

In this post I will explain how to use WebClient along with WebClientTest.

Overview of WebClient

WebClient is a non-blocking, reactive client for performing HTTP requests with Reactive Streams back pressure. WebClient provides a functional API that takes advantage of Java 8 lambdas.

By default, WebClient uses Reactor Netty as the HTTP client library but others can be plugged in through a custom ClientHttpConnector.

To start using WebClient with remote Rest APIs, you need Spring WebFlux as your project dependency.

You can create a WebClient using one of the static factory methods create() or the overloaded create(String). Another approach is to obtain a builder() to create and configure an instance.

In this post, we’ll look at both the approaches.

The Application

For this post, I have a Spring 5 reactive RESTful service that acts as a Producer. It continuously emits streams of data wrapped in a Flux. We will access the producer from a second service using WebClient.

We will also use WebClient to access the OMDB API, a free REST API to query movie information.

The existing Spring 5 Reactive RESTful service (Producer) is comprised of a controller and a MovieEvent domain object that models an event. The service layer produces a stream of MovieEvent with a delay of 1 second continuously.

As this post is on WebClient, I won’t go into the Producer side. The Producer is a Maven project that you can download from the link provided at the end of this post. You need to clone it, import it to your IDE, and run.

I have imported the producer as a Maven Project to IntelliJ and got it running on an embedded Netty server, as shown in this Figure.

Spring WebFlux Producer Output from Netty

WebClient in the API Consumer

The API consumer is a Spring Boot project that uses WebFlux. The consumer communicates with two services:

  1. OMDB API to retrieve movie information by name, and ID.
  2. Our local Producer to consume event streams.

To access the OMDB API, get your free API access key here.

The Maven POM of the consumer is this.

pom.xml

The Domain Models

Our domain model is a Movie POJO with fields to hold movie information returned by the OMDB API.

The Movie POJO is this.

Movie.java

Our second domain model is MovieEvent that models an event to be received from the Producer.

The MovieEvent POJO is this.

MovieEvent.java

The Service Interfaces

The service layer is composed of two service interfaces – MovieClientService and MovieClientEventService.

The service interfaces are as follows.

MovieClientService.java

MovieClientEventService.java

The Service Implementations

The MovieClientServiceImplementation class implements the MovieClientService interface. In this class, we will use WebClient to send requests to the OMDB API to search a movie by ID and title.

For this example, I have specified the OMDB API access key in the application.properties file, like this.

The code of the MovieClientServiceImplementation class is this.

MovieClientServiceImplementation.java

In the preceding code:

  • The constructor of the MovieClientServiceImplementation creates a WebClient using a WebClient.Builder obtained from a call to the builder() method.
  • Line 24 – Line 27 configures the WebClient through method chaining with the base URL and the CONTENT_TYPE and USER_AGENT headers.
  • Line 30 – Line 35 implements the searchMovieByTitle() method to perform a request with the API key and movie title. The retrieve() method returns a WebClient.ResponseSpec whose bodyToMono() extracts the response body to a Mono.
  • Line 38 -Line 43 implements the searchMovieById() method in the same way, but by passing the movie ID instead of the title in the URL.

The MovieClientEventServiceImpl class implements the MovieClientEventService interface to communicate with our producer of MovieEvent stream.

The MovieClientEventServiceImpl service implementation is this.

MovieClientEventServiceImpl.java

Note that Line 32 calls the exchange() method instead of retrieve() this time to receive the response. The exchange() method returns a Mono that represents the response body along with other information, such as status and headers. On the other hand, the retrieve() method we used earlier is a lightweight way to access the response body directly.

Learn more about WebClient in my Spring Framework 5 Online Course
Online Course – Spring Framework 5: Beginner to Guru

The Controller

The REST controller of the Consumer application define endpoints for clients to query for movies and subscribe to events.

The MovieController class is this.

MovieController.java

Testing Endpoints with WebTestClient

To test endpoints, Spring 5 WebFlux framework comes with a WebTestClient class. WebTestClient is a thin shell around WebClient. You can use it to perform requests and verify responses.

WebTestClient bind to a WebFlux application using a mock request and response, or it can test any web server over an HTTP connection.

Our first test uses WebTestClient to test the movie search endpoints exposed by out Producer RESTful service.

The code of the MovieClientServiceImplTest is this.

MovieClientServiceImplTest.java

In the preceding code:

  • Line 27 autowires in WebTestClient to the test class.
  • Line 31 – Line 36 mutates the response timeout property of WebTestClient and builds it.
  • Line 38 – Line 42 of the first test case sets up a GET request and performs the request through exchange()
  • Line 43- Line 46 after exchange() is a chained API workflow to verify responses.
  • Line 49 – Line 58 similarly tests the endpoint that accepts search requests of movies by title.

Our second test uses WebTestClient to test the event source endpoint exposed by out Producer RESTful service.

The code of the MovieClientServiceImplTest is this.

MovieClientEventServiceImplTest.java

Summary

One common question is whether WebClient is replacing the traditional RestTemplate. Not at this time. RestTemplate will continue to exist within the Spring Framework for the foreseeable future.

The primary differentiating factor is that RestTemplate continues to use the Java Servlet API and is synchronous blocking. This means, a call done using RestTemplate needs to wait till the response comes back to proceed further.

On the other hand, as WebClient is asynchronous, the rest call need not wait till response comes back. Instead when there is a response, a notification will be provided.

Get The Source!

Like all of my tutorials, the source code for this post is available on GitHub here.

Testing Spring Boot Online Course
Online Course – Testing Spring Boot: Beginner to Guru
0
Share

Spring Framework 5.0 is the first major release of the Spring Framework since version 4 was released in December of 2013. Juergen Hoeller, Spring Framework project lead announced the release of the first Spring Framework 5.0 milestone (5.0 M1) on 28 July 2016.

Now, a year later, we are looking forward to Release Candidate 3 (RC3) to be released on July 18th, 2017. This is expected to be the final release on the roadmap to the first GA (General Availability) release of Spring Framework 5.0.

I’m excited about the new features and enhancements in Spring Framework 5.0.

At a high level, features of Spring Framework 5.0 can be categorized into:

  • JDK baseline update
  • Core framework revision
  • Core container updates
  • Functional programming with Kotlin
  • Reactive Programming Model
  • Testing improvements
  • Library support
  • Discontinued support

JDK Baseline Update for Spring Framework 5.0

The entire Spring framework 5.0 codebase runs on Java 8. Therefore, Java 8 is the minimum requirement to work on Spring Framework 5.0.

This is actually very significant for the framework. While as developers, we’ve been able to enjoy all the new features found in modern Java releases. The framework itself was carrying a lot of baggage in supporting deprecated Java releases.

The framework now requires a minimum of Java 8.

Originally, Spring Framework 5.0 was expected to release on Java 9. However, with the Java 9 release running 18 months + behind, the Spring team decided to decouple the Spring Framework 5.0 release from Java 9.

However, when Java 9 is released (expected in September of 2017), Spring Framework 5.0 will be ready.

Core Framework Revision

The core Spring Framework 5.0 has been revised to utilize the new features introduced in Java 8. The key ones are:

  • Based on Java 8 reflection enhancements, method parameters in Spring Framework 5.0 can be efficiently accessed.
  • Core Spring interfaces now provide selective declarations built on Java 8 default methods.
  • @Nullable and @NotNull annotations to explicitly mark nullable arguments and return values. This enables dealing null values at compile time rather than throwing NullPointerExceptions at runtime.

On the logging front, Spring Framework 5.0 comes out of the box with Commons Logging bridge module, named spring-jcl instead of the standard Commons Logging. Also, this new version will auto detect Log4j 2.x, SLF4J, JUL ( java.util.logging) without any extra bridges.

Defensive programming also gets a thrust with the Resource abstraction providing the isFile indicator for the getFile method.

Core Container Updates

Spring Framework 5.0 now supports candidate component index as an alternative to classpath scanning. This support has been added to shortcut the candidate component identification step in the classpath scanner.

An application build task can define its own META-INF/spring.components file for the current project. At compilation time, the source model is introspected and JPA entities and Spring Components are flagged.

Reading entities from the index rather than scanning the classpath does not have significant differences for small projects with less than 200 classes. However, it has significant impacts on large projects.

Loading the component index is cheap. Therefore the startup time with the index remains constant as the number of classes increase. While for a compoent scan the startup time increases significantly.

What this means for us developers on large Spring projects, the startup time for our applications will be reduced significantly. While 20 or 30 seconds does not seem like much, when you’re waiting for that dozens or hundreds of times a day, it adds up. Using the component index will help with your daily productivity.

You can find more information on the component index feature on Spring’s Jira.

Now  @Nullable annotations can also be used as indicators for optional injection points. Using  @Nullable imposes an obligation on the consumers that they must prepare for a value to be null. Prior to this release, the only way to accomplish this is through Android’s Nullable, Checker Framework’s Nullable, and JSR 305’s Nullable.

Some other new and enhanced features from the release note are:

  • Implementation of functional programming style in GenericApplicationContext and AnnotationConfigApplicationContext
  • Consistent detection of transaction, caching, async annotations on interface methods.
  • XML configuration namespaces streamlined towards unversioned schemas.

Functional Programming with Kotlin

Spring Framework 5.0 introduces support for JetBrains Kotlin language. Kotlin is an object-oriented language supporting functional programming style.

Kotlin runs on top of the JVM, but not limited to it. With Kotlin support, developers can dive into functional Spring programming, in particular for functional Web endpoints and bean registration.

In Spring Framework 5.0, you can write clean and idiomatic Kotlin code for Web functional API, like this.

For bean registration, as an alternative to XML or @Configuration and @Bean, you can now use Kotlin to register your Spring Beans, like this:

spring framework 5.0 reactive is coming
Click here to learn about my new Spring Framework 5 course! Spring Framework 5: Beginner to Guru

Reactive Programming Model

An exciting feature in this Spring release is the new reactive stack Web framework.

Being fully reactive and non-blocking, this Spring Framework 5.0 is suitable for event-loop style processing that can scale with a small number of threads.

Reactive Streams is an API specification developed by engineers from Netflix, Pivotal, Typesafe, Red Hat, Oracle, Twitter, and Spray.io. This provides a common API for reactive programming implementations to implement. Much like JPA for Hibernate. Where JPA is the API, and Hibernate is the implementation.

The Reactive Streams API is officially part of Java 9. In Java 8, you will need to include a dependency for the Reactive Streams API specification.

Streaming support in Spring Framework 5.0 is built upon Project Reactor, which implements the Reactive Streams API specification.

Spring Framework 5.0 has a new  spring-webflux module that supports reactive HTTP and WebSocket clients. Spring Framework 5.0 also provides support for reactive web applications running on servers which includes REST, HTML, and WebSocket style interactions.

I have a detailed post about Reactive Streams here.

There are two distinct programming models on the server-side in spring-webflux:

  • Annotation-based with @Controller and the other annotations of Spring MVC
  • Functional style routing and handling with Java 8 lambda

With Spring Webflux, you can now create WebClient, which is reactive and non-blocking as an alternative to RestTemplate.

A WebClient implementation of a REST endpoint in Spring 5.0 is this.

Spring Framework 5 - Beginner to Guru
Click Here to learn about – Spring Framework 5 – Beginner to Guru!

While the new WebFlux module brings us some exciting new capabilities, traditional Spring MVC is still fully supported in Spring Framework 5.0.

Testing Improvements

Spring Framework 5.0 fully supports Junit 5 Jupiter to write tests and extensions in JUnit 5. In addition to providing a programming and extension model, the Jupiter sub-project provides a test engine to run Jupiter based tests on Spring.

In addition, Spring Framework 5 provides support for parallel test execution in Spring TestContext Framework.
For the reactive programming model, spring-test now includes WebTestClient for integrating testing support for Spring WebFlux. The new WebTestClient, similar to MockMvc does not need a running server. Using a mock request and response, WebTestClient can bind directly to the WebFlux server infrastructure.

For a complete list enhancements in the existing TestContext framework, you can refer here.

Of course, Spring Framework 5.0 still supports our old friend JUnit 4 as well! At the time of writing, JUnit 5 is just about to go GA. Support for JUnit 4 is going to be with the Spring Framework for some time into the future.

Library Support

Spring Framework 5.0 now supports the following upgraded library versions:

Discontinued Support

At the API level, Spring Framework 5.0 has discontinued support for the following packages:

  • beans.factory.access
  • jdbc.support.nativejdbc
  • mock.staticmock of the spring-aspects module.
  • web.view.tiles2M. Now Tiles 3 is the minimum requirement.
  • orm.hibernate3 and orm.hibernate4. Now, Hibernate 5 is the supported framework.

Spring Framework 5.0 has also discontinued support for the following libraries:

  • Portlet
  • Velocity
  • JasperReports
  • XMLBeans
  • JDO
  • Guava

If you are using any of the preceding packages, it is recommended to stay on Spring Framework 4.3.x.

Summary

The highlight of the Spring Framework 5.0 is definitely reactive programming, which is a significant paradigm shift. You can look at Spring Framework 5.0 as a cornerstone release for reactive programs. For the remainder of 2017 and beyond, you can expect to see child projects implement reactive features. You will see reactive programming features added to upcoming releases of Spring Data, Spring Security, Spring Integration and more.

The Spring Data team has already implemented reactive support for MongoDB and Redis.

It’s still too early to get reactive support with JDBC. The JDBC specification itself is blocking. So, its going to be some time before we see reactive programming with traditional JDBC databases.

While Reactive Programming is the shiny new toy inside of Spring Framework 5.0, it’s not going to be supported everywhere. The downstream technologies need to provide reactive support.

With the growing popularity of Reactive Programming, we can expect to see more and more technologies implement Reactive solutions. The reactive landscape is rapidly evolving. Spring Framework 5 uses Reactor, which is Reactive Streams compliant implementation. You can read more about the Reactive Streams specification here.

12
Share