This is a org.springframework.web.client.RestClient config
@Configuration
public class CloudConfig {
@Value("${experimental.host}")
String baseURI;
@Bean
RestClient restClient(RestClient.Builder builder){
return builder.baseUrl(baseURI).build();
}
}
This is service which does a call to external API
@Component
public class RequestService {
public String callAPI(int userID){
Map<String, Object> properties = Map.of("id", userID);
return restClient.post()
.uri("/external")
.body(properties)
.retrieve()
.body(String.class);
}
}
I get a list of user from db and in the loop call external API
@Service
public class RabbitMQProducer {
private UserRepository repository;
private RequestService requestService;
@Scheduled(fixedRate = 10000)
public void sendUserData(){
for(User user : repository.findAll()) {
String data = requestService.callAPI(user.getID);
......
}
}
}
What is a correct way to make a pause between each call because external api has constraine of 1 second to call ? I got error message from API "org.springframework.web.client.HttpClientErrorException$TooManyRequests: too many request 2 times in 1000 millseconds"
Is there any pattern or solution how to resolve that kind of problem ?
I think expected behavior:
call API --> 1 second wait --> call API --> 1 second wait ...
Easy way to fix that it's just to add Thread.sleep(1000) but i'm not sure that is a good solution
If you use Thread.sleep(1000), then it will make constraints of 1 call for 1 second, but it is not ideal because it will block the current thread.
1. Webflux & webClient
I use this.
2. Resilience4j
This is the rate-limiting library.
.
2. @Async
You should add @EnableAsync
+a, retry
I recommend you add retry to ensure that works properly. When working with external API that has a rate limiting, it is recommended to make some retry logic.