What is Spring Cloud OpenFeign, and how do you declare and enable a Feign client?
answer
- interface + @FeignClient = proxy
- @EnableFeignClients scans & registers
- name = service id, url = fixed host
- MVC annotations on methods
- spring-cloud-starter-openfeign
basics
~10 sOpenFeign lets you call another HTTP service by declaring a Java interface annotated with @FeignClient. You add @EnableFeignClients to a config class, and Spring generates a proxy that turns method calls into HTTP requests.
solid answer
~40 sSpring Cloud OpenFeign is a declarative REST client: instead of hand-writing HTTP calls with RestTemplate or WebClient, you define an interface, annotate it with @FeignClient(name = "..."), and put MVC-style annotations (@GetMapping, @PathVariable, etc.) on its methods. Spring creates a runtime proxy implementing the interface; each method call is translated into a real HTTP request, sent, and the response is deserialized into the return type. You activate scanning with @EnableFeignClients on a @Configuration/@SpringBootApplication class. The `name` (or `value`) identifies the client and, when using a service registry/load balancer, resolves to instances; a literal `url` bypasses discovery and targets a fixed host. You inject the interface anywhere like any other Spring bean.
code
java · 24 lines@SpringBootApplication
@EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@FeignClient(name = "catalog", url = "${catalog.url}")
public interface CatalogClient {
@GetMapping("/products/{id}")
Product getProduct(@PathVariable("id") Long id);
@PostMapping("/products")
Product create(@RequestBody NewProduct body);
}
@Service
public class ProductService {
private final CatalogClient catalog;
ProductService(CatalogClient catalog) { this.catalog = catalog; }
Product find(Long id) { return catalog.getProduct(id); }
}go deeper
Know that you declare an interface, annotate with @FeignClient, and enable scanning with @EnableFeignClients.
Understand name-vs-url, the proxy mechanism, and required starter dependencies.
Explain discovery/load-balancing resolution of name, contextId, and blocking nature vs WebClient.
Weigh Feign vs WebClient/RestClient at architecture level, discovery integration, and lifecycle of generated proxies.
## What OpenFeign is **Feign** is a declarative HTTP client library originally from Netflix. **Spring Cloud OpenFeign** integrates it into the Spring ecosystem so you can call remote HTTP APIs by writing only an *interface* — no client boilerplate. At startup Spring generates a dynamic **proxy** that implements the interface; when you call a method, Feign builds an HTTP request from the method's annotations/arguments, executes it, and converts the HTTP response back into the declared return type. ## The two core annotations - **`@EnableFeignClients`** — placed on a `@Configuration` or `@SpringBootApplication` class. It triggers a classpath scan for interfaces annotated with `@FeignClient` and registers a proxy bean for each. Without it, your `@FeignClient` interfaces are never turned into beans. You can narrow the scan with `basePackages` / `clients`. - **`@FeignClient`** — placed on the interface. Key attributes: - `name` / `value` — a logical client name. With a load balancer (Spring Cloud LoadBalancer) this is treated as a **service id** resolved via discovery. - `url` — a hardcoded absolute base URL (e.g. `https://api.example.com`). When present, discovery/load-balancing is bypassed and requests go straight to that host. Useful for third-party APIs. - `path` — a prefix prepended to every method mapping. - `configuration` — a per-client config class supplying custom beans (Encoder, Decoder, etc.). - `contextId` — disambiguates when two clients share the same `name`. - `fallback` / `fallbackFactory` — circuit-breaker fallbacks (require a CircuitBreaker on the classpath and enabled). ## Minimal example flow ``` @FeignClient(name = "catalog", url = "https://catalog.example.com") interface CatalogClient { @GetMapping("/products/{id}") Product getProduct(@PathVariable Long id); } ``` Calling `catalogClient.getProduct(42L)` issues `GET https://catalog.example.com/products/42`, then deserializes the JSON body into a `Product`. ## Dependencies You need `spring-cloud-starter-openfeign` on the classpath, and a Spring Cloud BOM to align versions. For load-balanced (`name`-only) clients you also need `spring-cloud-starter-loadbalancer` plus a discovery client. ## When to use it Great for internal service-to-service calls in a Spring Cloud microservice mesh, and for wrapping third-party REST APIs behind a typed interface. For reactive/streaming or high-concurrency non-blocking needs, prefer `WebClient` (Feign is blocking by default) — though a reactive `spring-cloud-openfeign` variant exists as a community project. ## Common gotchas - Forgetting `@EnableFeignClients` → the interface isn't a bean, injection fails. - Using plain JAX-RS annotations expecting them to work — the default Spring contract expects Spring MVC annotations. - Assuming Feign is non-blocking — the default synchronous client blocks the calling thread.
- What is the difference between the `name` and `url` attributes of @FeignClient?`name` is a logical client id; with a load balancer it resolves to service instances via discovery. `url` hardcodes an absolute base URL and bypasses discovery/load-balancing. You can supply both — `url` wins for the target host while `name`/`contextId` still identify the client's configuration context.
- Is a default Feign client blocking or non-blocking?Blocking. The default synchronous Feign client executes the HTTP call on the calling thread and waits for the response. For non-blocking I/O you'd use WebClient instead.
saying these in an interview costs you the question
- Thinking @FeignClient alone works without @EnableFeignClients somewhere
- Believing Feign is reactive/non-blocking by default
- Assuming you must write an implementation class for the interface
- Confusing `url` and `name` — thinking `name` is just a label with no discovery meaning