skip to content

In @FeignClient(name = "order-service"), what is that name and how does the call reach a real host?

level: juniorimportance: must knowfreq 70%

answer

  1. name = logical service id, not a host
  2. no url -> LoadBalancer + DiscoveryClient
  3. round-robin picks an instance
  4. url set -> discovery bypassed
  5. Ribbon retired, SCLB now

basics

~20 s

The name is a logical service id, not a hostname. Feign hands it to Spring Cloud LoadBalancer, which asks the DiscoveryClient for live instances of that service and picks one, so you never hard-code a URL.

solid answer

~40 s

The name is a logical service identifier — the id other instances register under in the service registry (Eureka, Consul, Kubernetes, etc.). When you don't supply a url, the Feign client is wrapped so that at call time the pseudo-URL http://order-service/... is intercepted: Spring Cloud LoadBalancer asks the DiscoveryClient for the currently registered instances of "order-service", chooses one (round-robin by default), and rewrites the request to that instance's real host:port. This decouples callers from physical addresses, lets instances scale up/down freely, and spreads load. If you instead set url="http://localhost:8080", the name becomes just a bean identifier and no discovery or load balancing happens — you talk to that fixed address.

code

java · 10 lines
java
@EnableFeignClients
@SpringBootApplication
public class App { }

// "order-service" is a service id resolved via discovery + load balancing
@FeignClient(name = "order-service")
public interface OrderClient {
    @GetMapping("/orders/{id}")
    OrderDto getOrder(@PathVariable("id") long id);
}

go deeper

for a junior

Know: name is a service id, not a URL; discovery + load balancer turn it into a real host.

for a middle

Explain the FeignBlockingLoadBalancerClient wrapper and DiscoveryClient lookup, and the url bypass.

for a senior

Contrast SCLB vs retired Ribbon, mention default round-robin and re-resolution per call.

for a principal

Discuss discovery source pluggability (Eureka/Consul/K8s), staleness of instance lists, and failure modes when no instances are registered.

## What Feign is Spring Cloud OpenFeign lets you declare an HTTP client as a Java interface annotated with `@FeignClient`; Spring generates a proxy that turns method calls into HTTP requests. You enable it with `@EnableFeignClients` on a configuration class. ## The `name` attribute `@FeignClient(name = "order-service")` — the `name` (aliased as `value`) is a **logical service id**, not a DNS name or URL. It's the identity that instances of that service register under in a **service registry** (a directory of running instances). Common registries: - Netflix Eureka, - HashiCorp Consul, - Spring Cloud Kubernetes. Spring reads the registry through the `DiscoveryClient` abstraction. ## How the name becomes a host When no `url` is given, Spring Cloud wraps the Feign client with `FeignBlockingLoadBalancerClient`. 1. At request time Feign builds a pseudo-URL like `http://order-service/orders/42`. 2. The wrapper sees the host `order-service`, treats it as a service id, and delegates to **Spring Cloud LoadBalancer (SCLB)**. 3. SCLB calls the `DiscoveryClient` to get the list of currently-registered instances (e.g. `10.0.1.5:8080`, `10.0.1.6:8080`), 4. applies a load-balancing strategy (**round-robin by default** via `RoundRobinLoadBalancer`), 5. and rewrites the request to the chosen instance's real `host:port`. **Why this matters.** You never hard-code addresses. Instances can scale out, restart, or move IPs; the registry keeps the list fresh, and every call re-resolves. Load is also spread across instances. ## The `url` escape hatch If you write `@FeignClient(name = "order-service", url = "http://localhost:8080")`, discovery and load balancing are **bypassed** — the `name` becomes only a bean/qualifier identifier and every call goes to that fixed URL. Useful for local testing or calling a fixed external API. ## Historical note Older Spring Cloud used **Netflix Ribbon** for client-side load balancing; Ribbon was removed and **Spring Cloud LoadBalancer** is now the default. Don't cite Ribbon as current. ## Gotcha — need a load balancer on the classpath If neither `url` nor a load-balancer implementation is present, you get an error like `No instances available` or the name can't be resolved. You need: - `spring-cloud-starter-loadbalancer` (usually pulled in transitively by a discovery starter) - plus a `DiscoveryClient` implementation.

  • What happens if you add url = "http://localhost:8080" to the annotation?
    Discovery and load balancing are bypassed; every call goes to that fixed URL and the name is only a bean identifier. Handy for local dev or a fixed external endpoint.
  • Which component actually picks the instance, and what is its default strategy?
    Spring Cloud LoadBalancer (via FeignBlockingLoadBalancerClient); the default strategy is round-robin (RoundRobinLoadBalancer).

saying these in an interview costs you the question

  • Thinking the name is a DNS hostname or must match a URL
  • Saying Ribbon does the load balancing (it was removed; SCLB replaced it)
  • Believing load balancing still happens when url is set

context