Services in a microservice architecture typically call each other either synchronously over HTTP REST APIs or asynchronously through a messaging queue, depending on whether an immediate response is needed.
Key Points: • Synchronous calls use REST (or gRPC) over HTTP, where the caller sends a request and waits for a response, usually carrying JSON payloads. • Asynchronous calls publish a message to a queue or topic, and the caller continues without waiting for the receiving service to process it. • REST calls are simpler to reason about but couple the caller to the callee's availability at request time. • Messaging decouples services in time, improving resilience if the downstream service is temporarily unavailable, at the cost of added complexity. • A service client library or a discovery-aware HTTP client is often used so the caller doesn't hardcode target URLs.
Example: An Order service might call a Payment service synchronously via a REST POST to charge a card, then publish an OrderPlaced event asynchronously to a queue that the Notification service consumes to send a confirmation email.
Code Example:
@Service
public class PaymentClient {
private final RestTemplate restTemplate;
public PaymentResponse charge(PaymentRequest request) {
return restTemplate.postForObject(
"http://payment-service/api/payments",
request,
PaymentResponse.class
);
}
}Interview Tip: A concise interview answer is:
"I'd use synchronous REST calls when the caller needs an immediate response, like charging a payment, and asynchronous messaging through a queue when the caller just needs to notify other services of something that happened. Messaging decouples services and improves resilience, at the cost of eventual rather than immediate consistency."