RabbitMQ — A Restaurant Booking Application using Spring Boot

Erarica Mehra
3 min readJan 19, 2021

I have built an application to receive, validate and process requests to book a table at a restaurant. A synchronous application would work fine with a limited number of requests. But as the application scales, it would not be able to handle a large number of requests at the same time. Hence we need to employ an asynchronous approach to handle booking requests.

The booking request we receive is validated and then pushed into the queue. The request is then processed asynchronously. If the requested slot is available, the request is saved in the database and both the user and the restaurant are notified about the status of the booking. In case the slot is unavailable, the user is notified.

The restaurant reserves the right to change the booking status at any time and, accordingly the user is notified. Emails are also processed and sent asynchronously so that in case an exception occurs, the normal processing of the application is not disrupted.

Below is a diagram to explain the working of the application:

A diagram to describe the usage of rabbitMQ in a restaurant booking application

Overview

  1. Send a POST booking request from Postman.

Here is a sample request:

POST : localhost:8080/booking/send

{
"userName": "Alice",
"restaurant":"Jungle Cafe",
"text":"options",
"to" : "abc@gmail.com",
"from" : "arf.cm@gmail.com",
"subject" : "Sub : Book a table",
"date": "2020-12-12",
"slot": "2 pm"
}

2. The request is validated. If valid, the request is enqueued to be processed further.

3. If the requested slot is available, the booking is stored in the database. The user and the restaurant are notified accordingly.

4. If the requested slot is unavailable, the user is notified accordingly.

5. The restaurant manager can change the status of a booking using the endpoint:

http://localhost:8080/booking/approve/{id}/{status}

Again both the restaurant and user are asynchronously notified when the status is changed.

RabbitTemplate

RabbitTemplate simplifies synchronous RabbitMQ access. Spring Boot automatically creates a connection factory and a RabbitTemplate, reducing the amount of code you have to write. However, you need to:

  • Configure a message listener.
@Service
public class MessageListener {
private static final Logger log = LoggerFactory.getLogger(MessageListener.class);@Autowired private EmailService emailService;@Autowired private BookingService bookingService;@RabbitListener(queues = ApplicationConstants.QUEUE_SPECIFIC_NAME)public void receiveMessage(BookingRequest bookingRequest) throws Exception {log.info("Received message as : {}", bookingRequest.toString());// TODO Continue further processing }
}
  • Declare the queue, the exchange, and the binding between them.
@EnableWebMvc
@Configuration
public class ApplicationConfig {
@Bean
public TopicExchange appExchange() {
return new TopicExchange(ApplicationConstants.EXCHANGE_NAME);
}

@Bean
public Queue appQueueSpecific() {
return new Queue(ApplicationConstants.QUEUE_SPECIFIC_NAME);
}

@Bean
public Binding declareBindingSpecific() {
return BindingBuilder.bind(appQueueSpecific())
.to(appExchange()).
.with(ApplicationConstants.ROUTING_KEY);
}


@Bean
public RabbitTemplate rabbitTemplate(final ConnectionFactory
connectionFactory) {
final RabbitTemplate rabbitTemplate = new
RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(
producerJackson2MessageConverter());
return rabbitTemplate;
}

@Bean
public Jackson2JsonMessageConverter
producerJackson2MessageConverter() {
return new Jackson2JsonMessageConverter();
}
}
  • Configure a component to send some messages to test the listener.
@Service
public class MessageSender {

private static final Logger log = LoggerFactory.getLogger(MessageSender.class);

@Autowired private final RabbitTemplate rabbitTemplate;

public MessageSender(final RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
}

public String sendMessage(BookingRequest request) {
log.info("Sending message...");
rabbitTemplate.convertAndSend(ApplicationConstants.EXCHANGE_NAME,
ApplicationConstants.ROUTING_KEY, request);
return "Request is being processed.";
}
}

Note:

It is important to note that all email notifications are sent asynchronously.

Source Code:

Please refer to the following link to view the source code on Github:

https://github.com/Erarica-Mehra/rabbitqueue-restaurant-booking

--

--