Declarative REST Client in Spring Boot (Spring 6 HTTP Interface)

  • 4.2/5
  • 5796
  • Jul 20, 2024

Feign, an early declarative REST client, was initially part of the Spring Cloud Netflix stack and later rebranded as Spring Cloud OpenFeign.

Before its introduction, crafting HTTP calls using RestTemplate involved repetitive code for each service interaction.

With Feign, developers could simply define an interface with method contracts mirroring the service's endpoints. Behind the scenes, proxy magic generated a fully functional HTTP client, eliminating the need for boilerplate code.

HTTP Interface (Spring Framework 6)

The recent release of Spring Framework 6 integrated this declarative REST client as a native part of the core web framework in the form of the HTTP Interface.

All the necessary components reside in the spring-web module, which is a transitive dependency for either the spring-boot-starter-web or spring-boot-starter-webflux modules.

Currently, the WebFlux dependency is essential due to the HttpServiceProxyFactory, responsible for client generation.

Internally, the new declarative HTTP clients leverage WebClient, the recommended client for HTTP requests since Spring 5.

This article demonstrates the capabilities of Spring Boot 3 HTTP Interface in the 'spring-boot-http-interface' service. The goal is to showcase its functionality by interacting with the 'rest-api-crud-server' service, acting as a CRUD REST API server, for fetching and modifying data.

1) API Server ("rest-api-crud-server")

This Spring Boot service serves as a straightforward API Server. Utilizing the Spring Boot HTTP Interface, we will invoke URLs on this server to retrieve or modify user data from another client service, namely 'spring-boot-http-interface.'

1.1) Create a Spring Boot Project

You can use Spring Initializr to generate a basic project structure.

Dependecnies

You should have following dependencies in your pom.xml file.

1.2) Create a 'User' Entity

Create a "User" class/record to represent users in your application.

1.3) Create a Controller

Create a controller class to handle HTTP requests.

1.4) Run Application

Open your project in an IDE (IntelliJ or Eclipse) or use the command line to navigate to your project directory. Run the application:

mvn spring-boot:run

The application will start, and you can access it at: http://localhost:8080.

1.5) Test Your APIs

You can use tools like Postman or cURL to test your API.

Or open the Swagger UI in the browser to test your APIs. It provides a convenient way to input parameters, make requests, and view responses.

Source Code: GitHub

2) API Client ("spring-boot-http-interface")

This is an additional Spring Boot service designed to function as a client for the "rest-api-crud-server" service. In this service, we will employ the Declarative Spring Boot REST Client (HTTP Interface) to retrieve or modify user data from the server ("rest-api-crud-server").

2.1) Create a Spring Boot Project

You can use Spring Initializr to generate a basic project structure.

Dependecnies

You should have following dependencies in your pom.xml file.

2.2) Create a User Entity

Create a "User" class or record for serializing and deserializing "user" data from the API Server ("rest-api-crud-server").

2.3) Create HTTP client (UserClient)

As you're aware, only an interface declaration with annotated fields and methods is required.

The primary annotation is @HttpExchange, serving as the root annotation for an HTTP interface and its exchange methods.

If applied at the interface level, it extends to all exchange methods, which proves beneficial for specifying attributes shared across all interface methods, such as content type or URL prefix.

Additionally, there are method-level annotations like @...Exchange for the common HTTP verbs (get, put, post, delete, and patch).

All the HTTP method-specific annotations are meta-annotated with @HttpExchange. Thus, @GetExchange("/books") is essentially equivalent to @HttpExchange(url = "/books", method = "GET").

The exchange methods support the following method parameters in the signature:

1) @PathVariable: Replaces a value with a placeholder in the request URL.
2) @RequestBody: Provides the body of the request.
3) @RequestParam: Adds request parameter(s).
4) @RequestHeader: Adds request header names and values.
5) @RequestPart: Can be used to add a request part (form field, resource, or HttpEntity, etc.).
6) @CookieValue: Adds cookies to the request.

When "content-type" is set to "application/x-www-form-urlencoded," parameters are encoded in the request body; otherwise, they are added as URL query parameters.

These annotations, such as @RequestParam, @PathVariable, or @RequestBody, are the same as those used in a Spring REST controller.

The HTTP exchange method return types can be one of the following:

1) Blocking
2) Reactive, i.e., Mono/Flux
3) Void, indicating no return value
4) HTTP status code and/or response headers

2.4) Create WebClient

At present, in contrast to OpenFeign, the client is not automatically provided through auto-configuration in a Spring Boot setup. Consequently, we construct a WebClient manually and associate it with our declarative HTTP client (UserClient) using the createClient method from HttpServiceProxyFactory.

2.5) Create a Controller

Create a controller class to manage HTTP requests. The UserClient can be autowired like any other bean and employed to retrieve or modify user data from the API Server.

2.6) Update application.yml

Configure the "server port" and other properties for the "client" in the application.yml (or application.properties) file.

2.7) Run Application

Open your project in an IDE (like IntelliJ or Eclipse) or use the command line to navigate to your project directory. Run the application:

mvn spring-boot:run

The application will start, and you can access it at: http://localhost:8080.

1.5) Test Your APIs

You can use tools like Postman or cURL to test your API.

Or open the Swagger UI in the browser to test your APIs. It provides a convenient way to input parameters, make requests, and view responses.

Source Code: GitHub

Index
How to Implement PostgreSQL Full-Text Search with Spring Boot

15 min

Spring's transaction management with the @Transactional annotation

9 min

Spring Boot Rest APIs with PostgreSQL (Spring Boot + Rest APIs)

15 min

Caching in Spring Boot (@Cacheable, @CacheEvict & @CachePut)

21 min

Declarative REST Client in Spring Boot (Spring 6 HTTP Interface)

13 min

Circuit Breaker in Spring Boot (Spring Cloud Circuit Breaker + Resilience4j)

12 min

Handling Concurrent Service Calls in a Spring Boot Application: Asynchronous vs. Reactive Approaches

11 min

Profiling a Spring Boot application with Pyroscope

7 min

Service discovery in Spring Boot (Spring Cloud + Netflix Eureka)

9 min

Dockerize Spring Boot app and Push image to DockerHub (Spring Boot + DockerHub)

4 min

Creating a Jenkins Pipeline for Spring Boot application

2 min

Monitoring Microservices (Spring Boot + Micrometer + Prometheus + Grafana)

7 min

Edge Server Pattern in Microservices (Spring Cloud Gateway)

7 min

Circuit Breaker Pattern in Microservices (Spring BOOT + Resilience4j)

4 min

Spring Cloud config server setup with Git

8 min

Distributed Tracing in Microservices (Spring Cloud Sleuth + Zipkin)

9 min

Circuit Breaker Pattern with Resilience4J in a Spring Boot Application

24 min

Deploying Spring Boot microservices on Kubernetes Cluster

12 min

Reactive programming in Java with Project Reactor

50 min

Spring Reactive with PostgreSQL (Spring Boot WebFlux + PostgreSQL)

13 min

Spring Reactive, Thymeleaf Hello World (Spring Webflux + Thymeleaf + JS/CSS)

9 min

Problem JSON (application/problem+json) in Spring WebFlux

15 min

Spring Boot Login/Logout (Spring Security + MySql + Thymeleaf)

21 min

Securing Server-to-Server Communication with "Spring Boot" & "OAuth 2"

18 min

Integrating Elasticsearch with a Spring Boot and PostgreSQL application

16 min

Sending Emails in Spring Boot via SMTP

7 min

How to create a basic Spring 6 project using Maven

5 min

Spring Boot, Thymeleaf Hello World (Spring Boot + Thymeleaf + JS/CSS)

9 min