Search code examples
javaspring-bootrestspring-webfluxflux

How do I submit requests to REST api in batches in SpringBoot?


I have a list of bulk request objects like

List<BulkRequests> bulkRequest;

I want submit them one by one to an external REST API I have already built a FiegnClient for that. Is there any optimised way to submit them one by one (submit next one only when the last one succeeds or in reactive manner) ? The bulk request class is something like this.

class BulkRequest {
  String traceId;
  List<MyRequest> myRequests;
}

Solution

  • For that you should maybe follow a reactive approach for send bulk requests.

    Considering that you feign client is already implemented or looks like this :

      @FeignClient(name = "external-api", url = "http://your-api-url.com")
    public interface ExternalAPIFeignClient {
        @PostMapping("/endpoint")
        Mono<ResponseEntity<?>> sendRequest(@RequestBody MyRequest request);
    }
    

    Keys things to do ar the following.

    • Configure my Bulk request service.

    • Map all of my requests from the batch

    • Use Flux or MonoFlux reactive approach to send them in bulk.

       @Service
       public class RequestService {
      
           private final ExternalAPIFeignClient externalAPIFeignClient;
      
           @Autowired
           public RequestService(ExternalAPIFeignClient externalAPIFeignClient) {
               this.externalAPIFeignClient = externalAPIFeignClient;
           }
      
           public Flux<ResponseEntity<?>> sendRequestsInBatch(List<MyRequest> bulkRequests) {
               return Flux.fromIterable(bulkRequests)
                       .flatMapSequential(request -> externalAPIFeignClient.sendRequest(request));
           }
       }
      

    fromIterable creates a reactive stream and flatMapSequential makes sure sequences executed one after the other.

    Your controller should look like this :

    @RestController
    @RequestMapping("/api")
    public class RequestController {
    
        private final RequestService requestService;
    
        @Autowired
        public RequestController(RequestService requestService) {
            this.requestService = requestService;
        }
    
        @PostMapping("/bulk-requests")
        public Flux<ResponseEntity<?>> sendBulkRequests(@RequestBody List<MyRequest> bulkRequests) {
            return requestService.sendRequestsInBatch(bulkRequests);
        }
    }
    

    Please bear in mind that you might need also to deal with error handling and retry mechanism, by implementing error and retry events.