ADR-019: Declarative HTTP Interface Client (RestClient) & Resilient External Service Integration¶
- Date: 2026-08-26
- Status: Accepted
- Phase: Phase 7C
Context & Problem Statement¶
During user onboarding (POST /api/v1/users), Payflow must verify whether a requested UPI ID is legitimate with an external upstream banking/NPCI verification gateway. In Spring Framework, outbound HTTP communication has historically used RestTemplate (now in maintenance/deprecated status) or third-party libraries like Netflix Feign / Spring Cloud OpenFeign (which add heavy runtime overhead and complex dependency trees). Furthermore, third-party network calls are inherently prone to transient connection failures, timeouts, and gateway outages that must not degrade core onboarding availability.
Considered Options¶
- Legacy
RestTemplate: Synchronous template client. Verbose, lacks fluent builder APIs, and deprecated in modern Spring Framework. - Spring Cloud OpenFeign: Declarative client annotations, but requires Spring Cloud BOM, Ribbon/LoadBalancer dependencies, and heavy reflection infrastructure.
- Declarative HTTP Interface Client backed by
RestClient(Chosen): Native Spring Framework 6.1+ / Spring Boot 4 feature (@HttpExchange/@GetExchange) withRestClientAdapterandHttpServiceProxyFactory, combined with Spring Retry (@Retryablewith exponential backoff, multiplier, and randomized jitter) and@Recovergraceful degradation.
Decision Outcome¶
Chosen Option: Declarative HTTP Interface Client via RestClient + Spring Retry (Option 3)
Rationale¶
- Modern Spring Standard:
RestClientprovides a fluent, synchronous HTTP client with full access to HTTP headers, timeouts, and status handlers without legacy template boilerplate. - Declarative Type Safety:
UpiValidationClientdefines contract interfaces with@HttpExchangeand@GetExchange, automatically proxied byHttpServiceProxyFactorywithout boilerplate client implementations. - Resilience via Exponential Backoff & Jitter: Transient network glitches and 5xx errors are retried up to 3 times with exponential backoff (
delay = 500ms,multiplier = 2.0,random = truejitter) to mitigate thundering-herd retry storms. - Non-Blocking Graceful Fallback: If upstream validation fails persistently or times out, the
@Recoverhandler (UpiValidationService.recoverFromValidationFailure) logs a warning and proceeds with registration. Third-party vendor outages never take down user registration. - Domain Rejection on Explicit Failure: If the external gateway explicitly reports
valid = false, registration is blocked withInvalidUpiException(422 Unprocessable Entity).
Consequences¶
- Positive: Zero third-party Feign dependencies, modern compile-time verifiable HTTP interface contracts, automated retry resilience with jitter, and high availability onboarding through graceful fallback.
- Negative / Trade-offs: Requires mock server setup (
MockRestServiceServer/@MockitoBean) in test suites whenpayflow.upi-validation.enabled=true.