Mastering Forest: A Practical Guide to Declarative HTTP Calls in Spring Boot
This article introduces the Forest Java HTTP client, explains its architecture and dynamic‑proxy mechanism, and provides step‑by‑step Spring Boot examples—including dependency setup, configuration, declarative interfaces, request annotations, parameter handling, and programmatic usage—so developers can quickly adopt declarative HTTP calls in their backend services.
1. Introduction
Forest is a Java HTTP client framework that supports both declarative and programmatic styles, allowing developers to send HTTP requests using interface definitions similar to RPC frameworks like Dubbo.
2. What is Forest?
Forest decouples HTTP request details from business code, managing URLs, headers, and other request metadata centrally. Callers invoke methods without worrying about the underlying HTTP implementation.
3. How Forest Works
Forest generates a concrete implementation of a user‑defined interface via dynamic proxies. The proxy validates request data, binds dynamic values, handles SSL, retries, and converts responses to Java types.
4. Architecture
The framework handles the front‑end part of HTTP request processing, wrapping lower‑level HTTP API frameworks.
5. Practical Example
5.1 Dependency Management
<code><dependency>
<groupId>com.dtflys.forest</groupId>
<artifactId>forest-spring-boot3-starter</artifactId>
<version>1.5.36</version>
</dependency></code>The example uses Spring Boot’s default Jackson JSON mapper; other mappers can be added as needed.
5.2 Simple Configuration
<code>forest:
backend: okhttp3
max-connections: 100
connect-timeout: 5000
read-timeout: 6000</code>Further configuration options are available in ForestConfigurationProperties .
5.3 Declarative Interface
<code>public interface UserClient {
@Request(
url = "http://localhost:8080/users",
headers = "Accept: application/json"
)
List<Map<String, Object>> list(@Query("area") String area);
}</code>The interface can be injected and used directly:
<code>@RestController
@RequestMapping("/forests")
public class ForestController {
private final UserClient userClient;
public ForestController(UserClient userClient) {
this.userClient = userClient;
}
@GetMapping("/users/{area}")
public Object users(@PathVariable String area) {
return this.userClient.list(area);
}
}</code>Testing the endpoint shows request details and timing in the console.
5.4 Supported Request Methods
Forest provides annotations such as @Get , @Post , @Put , and their @*Request equivalents. Example:
<code>@Get("http://localhost:8080/users")
Object get1();
@Post("http://localhost:8080/users")
Object post(@JSONBody User user);
@Put("http://localhost:8080/users")
Object put(@JSONBody User user);</code>5.5 Request Parameters
URL parameters can be supplied via placeholders, @Var annotations, or @Query annotations:
<code>@Get("http://localhost:8080/abc?a={0}&b={1}&id=0")
String send1(String a, String b);
@Get("http://localhost:8080/abc?a={a}&b={b}&id=0")
String send2(@Var("a") String a, @Var("b") String b);
@Get("http://localhost:8080/abc?id=0")
String send(@Query("a") String a, @Query("b") String b);
</code>Body parameters use @Body , @JSONBody , or @Form annotations. Example of form‑encoded body:
<code>@Post("http://localhost:8080/login")
Object login(@Body("username") String username, @Body("password") String password);
</code>Example of JSON body:
<code>@Post("http://localhost:8080/user")
Object save(@JSONBody User user);
</code>5.6 Interface‑Level Annotations
<code>@BaseRequest(
baseURL = "http://localhost:8080/users",
headers = {"Accept:application/json"},
sslProtocol = "TLS"
)
public interface UserClient {
@Request(url = "")
List<Map<String, Object>> list(@Query("area") String area);
@Post("")
R save(@JSONBody User user);
}</code>5.7 Programmatic Usage
<code>Object ret = Forest.get("http://localhost:8080/users").execute();
System.out.println(ret);
ForestRequest<?> request = Forest.get("http://localhost:8080/users");
request.backend("httpclient");
Object ret2 = request.execute();
request.addBody(new User("admin", 66));</code>Programmatic calls support extensive configuration; refer to the official documentation for more details.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.