Week 14

Architecture Patterns

Communication Patterns

Background Processing

Architectural Trade-offs

Messaging

Hands-on: RabbitMQ

Practice

Assignment

Backend Track

Introduction

The moment a system has more than one part, those parts must talk to each other. There are only two fundamental ways to do that: ask and wait for the answer (synchronous), or leave a message and move on (asynchronous). Think of a phone call versus a WhatsApp message: on a call, both sides must be available at the same time; a message can be picked up whenever the receiver is ready.

Synchronous: HTTP between your own services

In Week 6 you used RestClient to call an external weather API. Calling your own second service works exactly the same way โ€” the only thing that changes is the address.

Imagine a small shop system where order-service checks with stock-service before confirming an order:

@Bean
public RestClient stockRestClient(RestClient.Builder builder) {
    return builder
            .baseUrl("<http://stock-service:8080>")
            .build();
}

<aside> ๐Ÿ’ก

Where does the hostname stock-service come from? Inside a Docker Compose network, every service can reach the others by service name. You already used this in Week 11, when your application connected to the database at host postgres instead of an IP address.

</aside>

sequenceDiagram
    participant Browser
    participant Order as order-service
    participant Stock as stock-service
    Browser->>Order: POST /orders
    Order->>Stock: GET /stock/42
    Stock-->>Order: { "quantity": 3 }
    Order-->>Browser: 201 Created

Synchronous communication is simple and familiar: it is just the HTTP you already know, and the caller gets an immediate answer it can use in its own response.

When the other service is slow (or gone)

Synchronous also means your thread waits. If stock-service takes 10 seconds, your user waits 10 seconds. If it is down and you have no timeout, waiting threads pile up until your service becomes unhealthy too. This is a cascading failure: a problem in one service travels up the chain and takes the callers down with it.

<aside> โš ๏ธ

Every synchronous call to another service needs a timeout โ€” the connection and read timeouts you configured in Week 6. Failing fast with a controlled error is always better than hanging.

</aside>

๐Ÿ’ฌ order-service calls stock-service, which calls warehouse-service. warehouse-service hangs. What does the user see?

Asynchronous: send and move on

In asynchronous communication, the sender does not wait for the work to be done. It records or sends the request, immediately continues, and the work happens later.

You see this every time you upload a video to YouTube: the upload finishes and you instantly get "your video is being processed". The conversion happens in the background โ€” sometimes minutes later โ€” and neither you nor the upload page waits for it.

The trade-off: the services become decoupled (the receiver may be busy or even down for a moment without breaking the sender), but the flow is harder to follow. There is no single stack trace anymore โ€” answering "where is my task now?" depends on good logging, which is exactly what you learned in Week 13.

Synchronous Asynchronous
Waiting Caller blocks until the answer arrives Caller continues immediately
Coupling Receiver must be up and fast right now Receiver can be slow or briefly down
Answer Immediate Later โ€” or never (fire-and-forget)
Debugging One request, one trace Work spread over time and logs
Examples Check stock before confirming an order; log in Send a confirmation email; process a video; generate a report

Choosing between them

The rule of thumb: if the response to the user depends on the result, the call must be synchronous. If the work can finish after you have already responded, make it asynchronous.

๐Ÿ’ฌ A user registers on your site. Which parts must be synchronous, and which can be asynchronous?

Summary

Synchronous communication between your own services is Week 6's RestClient pointed at a Compose service name โ€” plus timeouts, always. Asynchronous communication decouples services and absorbs slowness, at the price of traceability. In the next chapter you will meet the simplest forms of asynchronous work inside one application โ€” and discover where they stop being enough.

Extra resources


The HackYourFuture curriculum is licensed underย CC BY-NC-SA 4.0 *https://hackyourfuture.net/*

CC BY-NC-SA 4.0 Icons

Built with โค๏ธ by the HackYourFuture community ยท Thank you, contributors

Found a mistake or have a suggestion? Let us know in the feedback form.