In the era of microservices, HTTP calls are as ubiquitous as air. Writing HTTP requests the traditional way? The overwhelming presence of
try-catch,HttpClientconfigurations, andJSONparsing code can be suffocating. Today, let me introduce you to a declarative HTTP framework—Forest, which liberates your hands in the most elegant way!
1. What is Forest?
Forest is a lightweight HTTP client framework that abstracts HTTP requests into simple interface methods based on Java annotations and interface proxy technology. You only need to declare the interface without implementation, and it automatically handles all HTTP communication details!
Core Advantages:
- • ✨ Declarative Development: Define requests with annotations, say goodbye to hard coding
- • 🚀 Minimal and Efficient: Complete complex HTTP calls in just 5 lines of code
- • 🔧 Fully Featured: Supports HTTPS, file uploads, interceptors, JSON/XML serialization
- • 🌲 Flexible Extension: Can integrate with Spring, dynamic proxies, and other ecosystems
2. Quick Start in 3 Minutes
1. Add Dependency (Maven)
<dependency>
<groupId>com.dtflys.forest</groupId>
<artifactId>forest-spring-boot-starter</artifactId>
<version>1.5.31</version>
</dependency>
2. Declare HTTP Interface
@BaseRequest(baseURL = "https://api.github.com")
public interface GitHubClient {
// Get user information (automatically deserialize JSON)
@Get("/users/{username}")
User getUser(@Var("username") String username);
// Search with query parameters
@Get("/search/repositories")
RepoResult searchRepos(@Query("q") String keyword);
// Submit JSON data (automatically serialize object)
@Post("/post/create")
Result createPost(@Body Post post);
}
3. Call the Interface (Automatically Injected in Spring Environment)
@Autowired
private GitHubClient gitHubClient;
public void getUserInfo() {
User user = gitHubClient.getUser("octocat");
System.out.println(user.getName()); // Output: The Octocat
}
3. Practical Scenario Examples
1. Dynamic URL + Request Headers
@Get(url = "{url}", headers = "Authorization: Bearer ${token}")
String fetchData(@Var("url") String url, @Var("token") String token);
2. File Upload
@Post(url = "/upload", contentType = "multipart/form-data")
String uploadFile(@PartFile("file") File file);
3. Asynchronous Call + Callback
@Get("/async")
Future<String> asyncRequest(OnSuccess<String> onSuccess);
// When calling
asyncRequest(result -> System.out.println("Asynchronous result: " + result));
4. Custom Interceptor (Logging/Retries)
// Define interceptor
public class RetryInterceptor implements Interceptor {
@Override
public void onError(ForestRequest request, ForestResponse response) {
request.addRetryCount(); // Automatically retry
}
}
// Bind to interface
@BaseRequest(interceptor = RetryInterceptor.class)
public interface PaymentApi { ... }
4. Why Choose Forest?
| Traditional Method | Forest Solution |
| Each call requires initializing HttpClient | ✅ Global connection pool reuse |
| Manually concatenating URL/parameters | ✅ Annotations automatically construct |
| Hard-coded JSON parsing | ✅ Automatic object mapping |
| Repeatedly writing try-catch | ✅ Unified exception handling |
Actual tests show a reduction in code volume by 70%+, with significantly improved readability!
5. Advanced Techniques
- 1. Integrate with Spring Boot: Add
@ForestScanannotation to scan interfaces - 2. Custom Codec: Implement
ForestEncoderto handle special serialization - 3. HTTPS Certificate Configuration: Bind keys using
@SSLannotation - 4. Mock Testing: Use
@Mockannotation to simulate response data
// Mock testing example
@Mock(response = "{\"name\": \"Mock User\"}")
@Get("/mock/user")
User mockUser();
Conclusion
Forest uses declarative programming to revolutionize the traditional HTTP calling model, freeing Java developers from mechanical coding. Its design philosophy is as its name suggests—like a forest, it embraces everything while maintaining simplicity and order.
Project Address: https://github.com/dromara/forestSlogan: Write less code, create more value!
END
Click the card below to follow me↓↓↓