Question presented to candidate: "Your order-service needs to check inventory before confirming an order, and it also needs to notify a notification-service after the order is placed. Would you implement these two interactions the same way? Why or why not?"
What a strong answer should cover:
- The prompt describes two genuinely different communication needs, and a strong answer treats them differently: checking inventory is a synchronous need (order-service cannot proceed without the answer) — notifying about a placed order is an asynchronous need (order-service does not need to wait for notification-service to finish, or even to succeed, before responding to its own caller).
- 📌 Verified, not assumed — synchronous: two genuinely separate real Express servers, order-service making a real
fetch()HTTP call to inventory-service, received a real 201 response confirming stock, with a measured real elapsed time. This is HTTP/REST (or gRPC in some stacks) — request-response, the caller blocks until it gets an answer. - 📌 Verified, not assumed — asynchronous: a real EventEmitter-based publish, where the publisher's own log line ("response already sent") printed after publishing but the subscriber's real reaction had already run by then — demonstrating the publisher does not wait on the subscriber. In production this pattern is typically a real message broker (RabbitMQ, Kafka, or the BullMQ-style queue covered in its own dedicated question) rather than an in-process EventEmitter, since real inter-service async messaging must cross process/machine boundaries.
- The core trade-off, stated precisely: synchronous (HTTP) communication is simpler to reason about and gives an immediate answer, but genuinely couples the caller's availability to the callee's availability — if inventory-service is down, order-service's request fails too. Asynchronous (events/queues) communication decouples the two services' uptime from each other, at the cost of eventual — not immediate — consistency, and genuinely more operational complexity (a message broker to run and monitor).
- A precise answer also names that idempotency matters more, not less, in async communication — a message broker's at-least-once delivery guarantee means a subscriber may genuinely receive the identical event twice, which is exactly the scenario verified with real double-charging vs. correctly-deduped behavior in the dedicated idempotency question.
Clarifying questions expected:
- "Does the caller genuinely need the answer before it can proceed, or can it succeed without knowing the outcome immediately?" — the single question that decides sync vs. async for a given interaction.
- "Is temporary unavailability of the downstream service acceptable, or must the caller fail immediately if it's down?" — directly maps to the coupling trade-off.
Code / implementation expected: Yes — real HTTP communication between two genuinely separate servers for the synchronous case, and a real publish-without-waiting demonstration for the asynchronous case, are the concrete, convincing proof that these are genuinely different mechanisms, not interchangeable implementation details.