skip to content

Explain the difference between the name and url attributes of @FeignClient and when load balancing kicks in.

level: middleimportance: should knowfreq 55%

answer

  1. name = service id (load-balanced)
  2. url = fixed address (no LB)
  3. url present -> discovery skipped
  4. name still required with url (bean/context id)
  5. same name twice -> need contextId

basics

~10 s

name is a logical service id resolved through discovery and load-balanced across instances. url is a hard-coded absolute address that skips discovery entirely. If url is present, no load balancing happens.

solid answer

~40 s

Both name and url identify where the client sends requests, but they behave oppositely. name (alias value) is a logical service id: with only name set, Spring wraps the client with FeignBlockingLoadBalancerClient, so each call asks Spring Cloud LoadBalancer to pick a live instance of that service from the DiscoveryClient — this is where client-side load balancing happens. url is an absolute address (http://host:port); when present it takes precedence, discovery and load balancing are skipped, and every request goes straight to that address. name is still required even when url is set, because it's used as the bean/context identifier and to look up per-client configuration. So the rule of thumb: name-only = discovery + load-balanced; name + url = fixed target, no load balancing.

code

java · 11 lines
java
// Load-balanced: resolves via discovery, round-robins instances
@FeignClient(name = "order-service")
interface OrderClient { /* ... */ }

// Fixed target: no discovery, no load balancing
@FeignClient(name = "payments-external", url = "https://api.payments.example.com")
interface PaymentsClient { /* ... */ }

// Two clients, same service id -> disambiguate with contextId
@FeignClient(name = "order-service", contextId = "orderQuery", path = "/query")
interface OrderQueryClient { /* ... */ }

go deeper

for a junior

Know name = load-balanced service id, url = fixed address that skips discovery.

for a middle

Explain that name is still needed as context id and introduce contextId for duplicate names.

for a senior

Discuss when hard url is legitimate (external APIs, dev) vs a discovery smell, and blank-url quirks.

for a principal

Weigh operational trade-offs: registry dependency vs static config, and multi-client context isolation.

**The two attributes.** - `name` (alias `value`) — a **logical service id**. Required. It identifies (a) the target service in discovery/load balancing, and (b) the Feign 'context' used to resolve per-client configuration and beans. - `url` — an **absolute address** (`http://host:port` or a full base URL). Optional. When set, it **wins**: the client sends directly to it. **When load balancing kicks in.** Client-side load balancing happens **only when `url` is absent**. In that case Spring Cloud registers a `FeignBlockingLoadBalancerClient` (for the blocking stack) that, per request, hands the service id to **Spring Cloud LoadBalancer**, which pulls instances from the `DiscoveryClient` and selects one (round-robin default). Set `url`, and that whole path is bypassed — Feign uses its plain `Client` (e.g. `Client.Default`, or an Apache HttpClient/OkHttp-backed client) against the fixed address. No registry lookup, no instance selection. **Why name is still required with url.** Even with a hard URL, Spring needs an identifier to build the client's isolated child application context, wire per-client `configuration`, and name the bean. That's why omitting `name` while setting `url` is invalid. **`contextId` — sharing a name across clients.** If two `@FeignClient` interfaces use the **same** `name` (e.g. both target `order-service` but different paths), the bean names collide. Add `contextId = "..."` to give each its own context while still targeting the same service id. Without it you get a bean-definition conflict at startup (unless bean overriding is enabled). **`path`.** A `path` attribute prepends a common prefix to every method mapping (e.g. `path = "/api/v1"`), orthogonal to name/url. **Gotchas.** - Using a property placeholder in `url` (e.g. `url = "${order.url:}"`) that resolves to empty does **not** re-enable load balancing in older versions the way you'd expect — behavior around blank url has varied; prefer omitting url entirely to get load balancing. - Hard-coding `url` in production defeats the purpose of discovery — usually a smell outside local/dev or fixed third-party APIs. - If you set `url` but forget the scheme (`http://`), resolution fails.

  • Two @FeignClient interfaces both use name = "order-service". What breaks and how do you fix it?
    Their Feign context/bean names collide, causing a bean-definition conflict at startup. Give each a distinct contextId so they get separate contexts while still targeting the same service id.

saying these in an interview costs you the question

  • Claiming load balancing still applies when url is set
  • Saying name is optional when url is provided
  • Thinking url and name are interchangeable synonyms

context