Using CompletableFuture.supplyAsync for Asynchronous REST API Calls in Spring Boot
Using CompletableFuture.supplyAsync for Asynchronous REST API Calls in Spring Boot
In modern web applications, performance and responsiveness are crucial. One way to enhance these aspects is by using asynchronous processing. In a Spring Boot application, you can leverage CompletableFuture to perform non-blocking operations. This article will demonstrate how to use CompletableFuture.supplyAsync for making asynchronous REST API calls.
1. Introduction to CompletableFuture
CompletableFuture is a part of the java.util.concurrent package and is designed for asynchronous programming in Java. It represents a future result of an asynchronous computation and allows you to write non-blocking code more easily. The supplyAsync method is a key feature that enables you to execute a task asynchronously.
2. Setting Up Your Spring Boot Project
First, ensure you have a Spring Boot project. You can create one using Spring Initializr or your preferred IDE. Include the necessary dependencies, such as spring-boot-starter-web for building RESTful APIs.
Here's an example pom.xml setup if you're using Maven:
xml<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
3. Making Asynchronous API Calls
Let's create a simple example where we make asynchronous REST API calls using CompletableFuture.supplyAsync.
- Define a REST Controller
Create a REST controller that will handle incoming requests and use CompletableFuture to call another REST service asynchronously.
javaimport org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
@RestController
@RequestMapping("/api")
public class MyController {
@Autowired
private ApiService apiService;
@GetMapping("/async-call")
public CompletableFuture<String> asyncCall() {
return CompletableFuture.supplyAsync(() -> apiService.callExternalApi());
}
}
- Create a Service for API Calls
In this service class, we will simulate an external API call. You can use RestTemplate or WebClient from Spring for making actual HTTP requests. Here, we'll use RestTemplate for simplicity.
javaimport org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class ApiService {
private final RestTemplate restTemplate = new RestTemplate();
public String callExternalApi() {
// Simulate a REST API call
String url = "https://jsonplaceholder.typicode.com/posts/1";
return restTemplate.getForObject(url, String.class);
}
}
- Configure
RestTemplateBean (Optional)
You can also define a RestTemplate bean in your configuration class for better testability and configuration.
javaimport org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class AppConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
4. Testing the Application
Run your Spring Boot application and navigate to http://localhost:8080/api/async-call in your browser or API client. You should see the JSON response from the external API.
5. Explanation
CompletableFuture.supplyAsync: This method runs the providedSupplierfunction asynchronously. It returns aCompletableFuturethat will complete with the result of the function once it is done.callExternalApi: This method simulates making an external API call. In a real-world scenario, you might handle more complex logic, error handling, and timeouts.
6. Conclusion
Using CompletableFuture.supplyAsync allows you to perform REST API calls asynchronously in a Spring Boot application. This approach improves the responsiveness of your application by not blocking the main thread while waiting for external API responses.
Feel free to expand on this example by integrating more complex logic, error handling, and configuring RestTemplate or WebClient to suit your needs.
Comments
Post a Comment