# Messaging

## Context

You have applied the \[\[Microservice architecture]] pattern. Services must handle requests from the application's clients. Furthermore, services often collaborate to handle those requests. Consequently, they must use an inter-process communication protocol.

## Forces

* Services often need to collaborate
* Synchronous communicate results in tight runtime coupling, both the client and service must be available for the duration of the request

## Problem

How do services in a microservice architecture communicate?

## Solution

Use asynchronous messaging for inter-service communication. Services communicating by exchanging messages over messaging channels.

There are several different styles of asynchronous communication:

* Request/response - a service sends a request message to a recipient and expects to receive a reply message promptly
* Notifications - a sender sends a message a recipient but does not expect a reply. Nor is one sent.
* Request/asynchronous response - a service sends a request message to a recipient and expects to receive a reply message eventually
* Publish/subscribe - a service publishes a message to zero or more recipients
* Publish/asynchronous response - a service publishes a request to one or recipients, some of whom send back a reply

## Examples

There are numerous examples of asynchronous messaging technologies

* Apache Kafka
* RabbitMQ

`OrderService` from the [FTGO Example application](https://github.com/microservices-patterns/ftgo-application) publishes an `Order Created` event when it creates an `Order`.

```java
public class OrderService {

  ...

  public Order createOrder(long consumerId, long restaurantId,
                           List<MenuItemIdAndQuantity> lineItems) {
    Restaurant restaurant = restaurantRepository.findById(restaurantId)
            .orElseThrow(() -> new RestaurantNotFoundException(restaurantId));

    List<OrderLineItem> orderLineItems = makeOrderLineItems(lineItems, restaurant);

    ResultWithDomainEvents<Order, OrderDomainEvent> orderAndEvents =
            Order.createOrder(consumerId, restaurant, orderLineItems);

    Order order = orderAndEvents.result;
    orderRepository.save(order);

    orderAggregateEventPublisher.publish(order, orderAndEvents.events);

    OrderDetails orderDetails = new OrderDetails(consumerId, restaurantId, orderLineItems, order.getOrderTotal());

    CreateOrderSagaState data = new CreateOrderSagaState(order.getId(), orderDetails);
    createOrderSagaManager.create(data, Order.class, order.getId());

    meterRegistry.ifPresent(mr -> mr.counter("placed_orders").increment());

    return order;
  }
}
```

## Resulting context

This pattern has the following benefits:

* Loose runtime coupling since it decouples the message sender from the consumer
* Improved availability since the message broker buffers messages until the consumer is able to process them
* Supports a variety of communication patterns including request/reply, notifications, request/async response, publish/subscribe, publish/async response etc

This pattern has the following drawbacks:

* Additional complexity of message broker, which must be highly available

This pattern has the following issues:

* Request/reply-style communication is more complex

## Related patterns

* The \[\[Saga]] pattern and \[\[CQRS]] pattern use messaging
* The \[\[Transactional Outbox]] pattern enables messages to be sent as part of a database transaction
* The \[\[Externalized configuration]] pattern supplies the (logical) message channel names and the location of the message broker
* The \[\[Domain-specific protocol]] pattern is an alternative pattern
* The \[\[RPI]] pattern is an alternative pattern

## See also

* My book [Microservices patterns](https://microservices.io/book) describes inter-communication in depth
* [Enterprise Integration Patterns](http://www.enterpriseintegrationpatterns.com/) - a comprehensive set of message patterns
* The [Event Tram framework](http://eventuate.io/), which implements transaction messaging for microservices


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gia-duong-duc-minh.gitbook.io/notes/computer/microservices/messaging.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
