Backend Development 4 min read

How to Use Spring 6/Boot 3 HTTP Interface for Declarative REST Clients

This guide explains how Spring 6/Boot 3’s built‑in HTTP interface lets you define declarative REST clients with annotated Java interfaces, covering setup, required Maven dependencies, interface creation, supported annotations, bean configuration, and unit testing with code examples.

Java Architecture Diary
Java Architecture Diary
Java Architecture Diary
How to Use Spring 6/Boot 3 HTTP Interface for Declarative REST Clients

http interface

Since Spring 6 and Spring Boot 3, the Spring framework can proxy remote HTTP services as Java interfaces annotated with specific annotations. Existing libraries such as OpenFeign and Retrofit remain usable, but the http interface adds built‑in support.

What is a declarative client

A declarative HTTP client aims to simplify writing Java HTTP clients. It automatically generates requests by processing annotations (officially called declarative or templated). With a declarative client, a HTTP request can be invoked like a local method, reducing coding effort and improving readability.

Example: to call the

/tenants

endpoint, define the following interface:

<code>public interface TenantClient {
    @GetExchange("/tenants")
    Flux<User> getAll();
}</code>

Spring provides a runtime implementation of the interface, allowing the request to be called as a Java method.

<code>@Autowired
TenantClient tenantClient;

tenantClient.getAll().subscribe();
</code>

Testing usage

1. Maven dependencies

<code><dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- For webclient support -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
</code>
Currently only the non‑blocking WebClient implementation of http interface is provided, so the webflux starter must be added.

2. Create an Http interface type

Add

@HttpExchange

on the interface to declare it as an http interface endpoint.

<code>@HttpExchange
public interface DemoApi {

    @GetExchange("/admin/tenant/list")
    String list();

}
</code>

Supported method‑level annotations:

<code>@GetExchange: for HTTP GET requests.
@PostExchange: for HTTP POST requests.
@PutExchange: for HTTP PUT requests.
@DeleteExchange: for HTTP DELETE requests.
@PatchExchange: for HTTP PATCH requests.
</code>

Supported parameter annotations:

<code>@PathVariable: placeholder parameter.
@RequestBody: request body.
@RequestParam: request parameter.
@RequestHeader: request header.
@RequestPart: form request.
@CookieValue: request cookie.
</code>

3. Inject the declarative client

Inject a WebClient with the target baseUrl into HttpServiceProxyFactory, then create the client.

<code>@Bean
DemoApi demoApi() {
    WebClient client = WebClient.builder().baseUrl("http://pigx.pigx.vip/").build();
    HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(client)).build();
    return factory.createClient(DemoApi.class);
}
</code>

4. Unit test the http interface

<code>@SpringBootTest
class DemoApplicationTests {
    @Autowired
    private DemoApi demoApi;

    @Test
    void testDemoApi() {
        demoApi.list();
    }
}
</code>
JavaSpringWebClientHttp InterfaceSpring Boot 3Declarative Client
Java Architecture Diary
Written by

Java Architecture Diary

Committed to sharing original, high‑quality technical articles; no fluff or promotional content.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.