Choose sync vs async and make contracts explicit: timeouts, retries, idempotency, and versioning.
Microservices don’t become complex because of code style—they become complex because services must communicate reliably under failure.
This section covers the core choices: request/response (REST/gRPC), messaging/event-driven communication, and how to keep data contracts stable as teams ship changes independently.
For Java engineers, the most important habits are the same everywhere: explicit timeouts, careful retry policy, idempotency for “at least once” delivery, and good observability around remote calls.