Search code examples
javarestrabbitmqspring-rabbit

How to return RabbitMQ data to the client (website user)


I'm studying RabbitMQ and I was wondering how to return the data it processes to the client (website user).

The process I'm thinking consists of a REST endpoint where the user requests something to be processed which takes about 5 seconds to finish. So the user requests it, the webservice forward the request to the RabbitMQ queue which will have up to 10 consumers in docker containers listening to it and ready to process the request. So far so good, I can do this. The thing is, how can I return the data to the user after the consumer has finished processing it? Having the design below in mind, there's the image for better understanding:

So in other words, it'll be something like:

1 - The producer (rest) receives the request and sends the message to the RabbitMQ.

2 - The RabbitMQ forward the message to any consumer listening.

3 - The consumer process the data.

4 - This is where I'm lost. How can I return the generated data to the client (website user)? One more thing, the user will be waiting for the request to end, no need to send it later.

For the sake of better details, I'm using java and for the rest part is spring boot.

Image: enter image description here


Solution

  • See Request Reply Messaging.

    Use one of the RabbitTemplate's sendAndReceive() methods.

    On the consumer side simply return a result from your @RabbitListener method.

    @RabbitListener(queues = "foo")
    public String process(String in) {
        return in.toUpperCase();
    }
    

    EDIT

    @SpringBootApplication
    public class So56025184Application {
    
        public static void main(String[] args) {
            SpringApplication.run(So56025184Application.class, args);
        }
    
        @Bean
        public ApplicationRunner runner(RabbitTemplate template) {
            return args -> {
                Scanner scanner = new Scanner(System.in);
                String toSend = scanner.nextLine();
                while (!"quit".equals(toSend)) {
                    System.out.println(template.convertSendAndReceive("q1", toSend));
                    toSend = scanner.nextLine();
                }
                scanner.close();
            };
        }
    
        @RabbitListener(queues = "q1")
        public String listen(String in) {
            return in.toUpperCase();
        }
    
        @Bean
        public Queue queue() { // RabbitAdmin will add this to the broker
            return new Queue("q1");
        }
    
    }
    

    You can send/receive rich objects (rather than simple strings), using Java serialization (and the default SimpleMessageConverter, or conversion to JSON, using the Jackson2JsonMessageConverter.