spring-framework
spring-framework copied to clipboard
Add Support to CompletableFuture as return type in Spring interfaces clients with RestClient
I suggest adding support for CompletableFuture and CompletionStage as a valid return type for methods in Spring client interfaces backed by RestClient and RestClientAdapter.
It would be great to provide the ExecutorService when creating the adapter or maybe leverage Async annotation
Example
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestClient;
import org.springframework.web.service.annotation.GetExchange;
import org.springframework.web.service.annotation.PostExchange;
import org.springframework.web.service.annotation.RequestBody;
import org.springframework.web.service.annotation.PathVariable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.service.invoker.HttpServiceProxyFactory;
public interface MyApiClient {
@GetExchange("/users/{id}")
CompletableFuture<User> getUser(@PathVariable int id);
@PostExchange("/users")
CompletableFuture<ResponseEntity<User>> createUser(@RequestBody User user);
@GetExchange("/items")
CompletableFuture<List<Item>> getAllItems();
}
@Configuration
public class ClientConfig {
@Bean
public MyApiClient myApiClient(RestClient.Builder restClientBuilder) {
RestClient restClient = restClientBuilder.baseUrl("https://api.example.com").build();
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(RestClientAdapter.forClient(restClient)).build();
return factory.createClient(MyApiClient.class);
}
}
@Service
public class MyService {
private final MyApiClient apiClient;
public MyService(MyApiClient apiClient) {
this.apiClient = apiClient;
}
public void processUser(int userId) {
apiClient.getUser(userId)
.thenAccept(user -> System.out.println("Retrieved user: " + user))
.exceptionally(ex -> {
System.err.println("Error fetching user: " + ex.getMessage());
return null;
});
}
}