Как строить интеграцию со сторонним API: адаптер, anti-corruption layer, таймауты, ретраи

↑ 5.5 Интеграции со сторонними API: 1С, Битрикс24, FHIR · → Следующая

По желанию~3 мин чтенияУровень: middle

Зачем это на собесе

Про надёжность: что вы делаете, когда внешний сервис медленный, падает или меняет формат.

Объяснение

Внешняя система не под вашим контролем: у неё свои модели, лимиты и простои. Поэтому интеграцию изолируют.

ПриёмЗачем
Адаптер (порт + реализация)доменный код зависит от своего интерфейса IPaymentGateway, а не от SDK
Anti-corruption layer (ACL)перевод чужой модели в свою; чужие термины не протекают в домен
Таймаутыограничить ожидание (на попытку и общий)
Retry с backoff + jitterпережить кратковременные сбои; только идемпотентные вызовы
Circuit breakerне долбить упавший сервис, быстро отказывать
Bulkhead / лимит параллелизмасбой интеграции не забирает все потоки/соединения
Кэш и деградацияотдать последнее известное значение
Идемпотентностьключи/дедупликация при повторах
Наблюдаемостьметрики, трейсы, логи запросов к внешним API (без секретов)
public interface IPaymentGateway { Task<PaymentResult> ChargeAsync(Charge c, CancellationToken ct); }
 
public class AcmePaymentGateway(HttpClient http) : IPaymentGateway
{
    public async Task<PaymentResult> ChargeAsync(Charge c, CancellationToken ct)
    {
        var resp = await http.PostAsJsonAsync("v2/charges", new AcmeChargeRequest(c.Amount.ToMinor(), c.Currency), ct);
        var dto = await resp.Content.ReadFromJsonAsync<AcmeChargeResponse>(ct);
        return AcmeMapper.ToDomain(dto!);       // ACL: чужие статусы → наши
    }
}
 
services.AddHttpClient<IPaymentGateway, AcmePaymentGateway>(c => c.BaseAddress = new("https://api.acme.example/"))
        .AddStandardResilienceHandler();

Нюансы и подводные камни

  • Ретраить платёж без ключа идемпотентности — риск двойного списания.
  • Без таймаута один медленный вызов занимает поток/соединение.
  • Контракт внешнего API меняется: контрактные тесты и толерантный парсинг.
  • Храните «сырой» ответ для отладки (осторожно с персональными данными).
  • Ограничения провайдера (rate limit) учитывайте на своей стороне.

Практика

  1. Оберните сторонний SDK адаптером и напишите тесты с fake.
  2. Настройте таймауты, retry и circuit breaker и сымитируйте отказ через WireMock.
  3. Добавьте метрики успешных/неуспешных вызовов.

Вопросы с ответами

Связанные темы