intermediate~2h

OpenFeign: Declarative REST Clients

Calling another service shouldn't need the same boilerplate every single time. This module is how OpenFeign turns a service-to-service call into one annotated Java interface.

Learning objectives

  • Beginner: Declare a Feign client interface and call another service through it like a local method.
  • Intermediate: Configure a Feign client's timeout and add a request/response logging interceptor.
  • Advanced: Combine a Feign client with Resilience4j so a downstream call degrades gracefully instead of hanging.

◆ The problem

Calling another service with a raw HTTP client means manually building the URL, setting headers, serializing the request body, deserializing the response, and handling errors — every single time, for every single downstream call, across every service in the system.

OpenFeign lets you declare an interface describing the call, and generates the actual HTTP client implementation for you at startup — calling another service looks exactly like calling a local method.

@FeignClient(name = "inventory-service") public interface InventoryClient { @GetMapping("/api/stock/{sku}") StockLevel getStock(@PathVariable("sku") String sku); } // calling code: StockLevel stock = inventoryClient.getStock("SKU-123");

💻 Code example

@FeignClient(name = "inventory-service") public interface InventoryClient { @GetMapping("/api/stock/{sku}") StockLevel getStock(@PathVariable("sku") String sku); }

@FeignClient(name = "inventory-service") doesn't point at a URL at all — that name is looked up through the exact service-discovery mechanism from the previous module, resolved to a currently-healthy instance via client-side load balancing, entirely transparent to the calling code.

feign: client: config: inventory-service: connect-timeout: 2000 read-timeout: 5000 logger-level: full

logger-level: full logs the entire request and response body for this specific Feign client — invaluable while debugging a service-to-service integration issue, and something to dial back down once the integration is confirmed working, since it's verbose in production.

⚠ Common real-world trap

A Feign client with no timeout configured, calling a downstream service that's hung (not crashed, just slow), ties up the calling thread indefinitely — under real load, this exhausts the caller's own thread pool, turning ONE slow downstream service into a cascading outage of the CALLER too.

This is precisely why Feign clients are almost always paired with the Circuit Breaker pattern (covered fully two modules from here) — a timeout alone stops one hung call, but a circuit breaker stops sending calls to a REPEATEDLY failing service at all, protecting the caller's own capacity.

✓ Quick recap

  • OpenFeign turns a service-to-service call into an annotated interface — no manual HTTP client boilerplate per call.
  • The name in @FeignClient resolves through service discovery, not a hardcoded URL.
  • Per-client timeout and logging configuration is essential — an unconfigured Feign client can hang indefinitely on a slow downstream call.
  • Feign is almost always paired with a Circuit Breaker, since a timeout alone doesn't stop a caller's thread pool from exhausting under sustained downstream failure.

Want a visual for this concept?

Generate a diagram tailored to “OpenFeign: Declarative REST Clients” — the AI picks whichever visual (flowchart, comparison, sequence, etc.) best fits.

Sign in to generate a visual →

Practice quiz

Next Step

Continue to WebClient: The Reactive HTTP Client← Back to all Spring Cloud chapters