Careeroza
Real World Example
Placing an Order Across Services
In a real checkout (Flipkart, Swiggy Instamart, BigBasket) one "Place order" click touches several services. ShopEase order-service uses three Feign clients:
POST /api/orders (gateway -> order-service)
|
|-- UserClient.getUser(42) user-service -> address, blocked?
|-- ProductClient.getProduct(7) product-service -> price, stock
|-- ProductClient.reserveStock(7, 2) product-service -> 204
|-- PaymentClient.charge("order-1001", ..) payment-service -> PAID
v
save Order(1001, PAID) -> 201 CreatedThe Service Code
@Service
@RequiredArgsConstructor
@Slf4j
public class PlaceOrderService {
private final UserClient userClient;
private final ProductClient productClient;
private final PaymentClient paymentClient;
private final OrderRepository orders;
@Transactional
public OrderResponse place(PlaceOrderRequest req) {
UserDto user = userClient.getUser(req.userId());
if (user.blocked()) throw new UserBlockedException(user.id());
ProductDto product = productClient.getProduct(req.productId());
BigDecimal total = product.price().multiply(BigDecimal.valueOf(req.quantity()));
Order order = orders.save(Order.pending(user.id(), product.id(), req.quantity(), total));
productClient.reserveStock(product.id(), new StockRequest(req.quantity()));
PaymentResponse payment = paymentClient.charge(
"order-" + order.getId(), // idempotency key
new ChargeRequest(order.getId(), total, req.paymentMode()));
order.markPaid(payment.paymentId());
log.info("Order {} placed for user {} total {}", order.getId(), user.id(), total);
return OrderResponse.from(order);
}
}Example
curl -X POST localhost:8080/api/orders -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"userId": 42, "productId": 7, "quantity": 2, "paymentMode": "UPI"}'Example output
HTTP/1.1 201 Created
{"orderId":1001,"status":"PAID","total":2998.00,"paymentId":"pay_9XfK2LmQ"}Note: If payment fails after stock was reserved, the stock must be released. Chains of synchronous calls make this hard; the Event-Driven module and the Saga pattern (advance level) solve it properly. Keep synchronous chains short: 2–3 hops at most.