Under The Hood
backend springboot Spring Cloud OpenFeign 4.x / Resilience4j 2.x

Feign Client Declarative HTTP & Resilience4j Circuit Breakers

Last updated
Prerequisites:
Spring Boot REST basics
Understanding of microservice communication and failure handling
  • spring
  • feign
  • resilience4j
  • circuit-breaker
  • microservices
  • http-client

Read at your depth

The practical view

OpenFeign makes HTTP clients declarative: @FeignClient(name = "users", url = "${users.url}") interface UserClient { @GetMapping("/users/{id}") User get(@PathVariable Long id); }. Spring creates a proxy implementing the interface that makes the HTTP calls. Resilience4j adds resilience patterns: CircuitBreaker, RateLimiter, Retry, TimeLimiter, Bulkhead. Wire them with annotations or a Registry: @CircuitBreaker(name = "users", fallbackMethod = "getFallback"). A circuit breaker trips after N failures, opens for a wait duration, then half-opens to test recovery.

The same idea in other frameworks

react equivalent
N/A — server-side Spring/Feign concern.

Legacy vs modern

Raw RestTemplate calls vs Feign + circuit breaker

Hand-rolled HTTP calls with manual error handling are verbose and have no failure isolation; Feign + Resilience4j makes the client declarative and resilient.

before → after
Manual RestTemplate call
ResponseEntity<User> r = restTemplate.getForEntity(
    "http://users/users/" + id, User.class); // ❌ OLD: manual, no resilience
Feign client with circuit breaker
@FeignClient(name = "users")
public interface UserClient { // ✅ NEW: declarative
  @GetMapping("/users/{id}") User get(@PathVariable Long id);
}

Interview gotchas

Context

This tests the fault-tolerance mechanics — interviewers want the CLOSED → OPEN → HALF_OPEN transitions and the sliding-window failure measurement that drives them.

The mechanical answer

The circuit breaker is a state machine. CLOSED (normal): calls pass through and outcomes are recorded in a sliding window (e.g. the last 10 calls or 10 seconds); when the failure rate exceeds the threshold (e.g. 50%), it transitions to OPEN. OPEN: calls fail fast (CallNotPermittedException) without hitting the downstream service — protecting it and freeing the caller's resources; this lasts waitDurationInOpenState (e.g. 5s). HALF_OPEN: after the wait, the breaker lets a small number of trial calls through to test whether the downstream has recovered; if they succeed (below the threshold), it returns to CLOSED; if they fail, it reopens. This prevents a broken service from being hammered while still allowing automatic recovery. The fallback method is invoked for the failing calls so the caller gets a graceful response instead of an exception.

Trap

The naive answer is 'a circuit breaker retries failed calls'. It blocks calls when open (fail-fast), it doesn't retry — retry is a separate Resilience4j pattern. Another trap: setting the window too small (e.g. 1 call) makes the breaker trip on a single blip, and too large delays detection. Candidates who describe the three states and the window math show real understanding.

Under The Hood — a multi-depth technical interview hub.

Third-party licenses Press ⌘ K to search.