Сервис каталога собирал карточку товара из трёх источников: основная БД с ценой и названием, отдельная БД с остатками склада, и внешняя БД отзывов. Всё жило в одном фасадном методе, который дергал три репозитория последовательно и склеивал результат.

Когда у БД отзывов случился сетевой таймаут на несколько минут, упали не только отзывы — упала вся карточка товара, включая цену и остатки, которые были полностью доступны. Фасад не делал разницы между критичной и некритичной зависимостью: исключение из третьего вызова прерывало весь метод до возврата ответа.

Исправили разделением на обязательные и опциональные данные. Цена и остатки — блокирующий вызов, без них карточки не показать. Отзывы — вызов с коротким таймаутом и fallback на пустой список при любой ошибке, вместо проброса исключения наверх.

ProductCard card = new ProductCard(price, stock); try { card.setReviews(reviewClient.fetchWithTimeout(productId, Duration.ofMillis(300))); } catch (Exception e) { card.setReviews(List.of()); }

Следом спросят, почему не сделали то же самое для остатков склада — ведь можно показать карточку без них тоже. Ответ в том, что отсутствие остатков меняет бизнес-смысл страницы: пользователь может купить то, чего нет. Решение, что считать критичным, а что нет, — не техническое, это вопрос к продукту, а не к архитектуре клиента.

Граница между «обязательно для ответа» и «желательно, но не критично» должна быть явной в коде, а не возникать случайно из-за порядка вызовов в одном методе.

senior·base — что спрашивают на самом деле


В этом посте были ссылки, но мы их удалили по правилам Сетки