Client REST en Java: trop facile avec Feign !

Igor Laborie

Java REST client with Feign


Igor Laborie

Expert Java & Web, MonkeyPatch


  1. Basic
    • CRUD operations, JSON
  2. Advanced
    • Async with RxJava
    • Circuit Breaker with Hystrix
    • HTTP/2 with Java 9


whois feign

Open Source: license Apache 2.0

A Netflix Project

Java 7+, Java 8 friendly

Not opinionated

du -h target/*.jar

Classes Fat jar
Jersey (JAX-RS 2) 112* 4,6 Mo
Retrofit 2 38 740 Ko
Feign 34 336 Ko

*: only into

See code on github

Most Java applications require a persistent class representing felines.

Hibernate Documentation ...

Most Java applications require a microservice for felines.

Any buzzword addicts

curl http://cats/swagger

Swagger Documentation

Run with: docker run -p 8080:8080 ilaborie/cats-microservice
See code on github

Live coding

CRUD operations, JSON

See code on github

Maven dependencies

Current lastest release: 9.3.1



import feign.*;
import java.util.List;
@Headers("Content-Type: application/json")
public interface CatClient {
  @RequestLine("GET /")
  List<Cat> findAll();
  @RequestLine("GET /{id}")
  Cat findById(@Param("id") String id);
  @RequestLine("POST /")
  Cat create(Cat newCat);
  @RequestLine("DELETE /{id}")
  Cat delete(@Param("id") String id);

Feign Builder

CatClient client = Feign.builder()
  // Create request body
  .encoder(new GsonEncoder())
  // Transform response body
  .decoder(new GsonDecoder())
  // Add custom header
  .requestInterceptor(template -> template.header("Date",
  // Tips: debug lite
  // Tips: debug with logger
  .logger(new Slf4jLogger())
  .target(CatClient.class, url);

Encoders & Decoders

Under the hood

No White/Dark Magic
The java.lang.reflect.Proxy allow you to dynamically implement the interface.

Use the to send and process HTTP requests. (by default)

Use the reflection API to extract meta-data.
If you prefer JAX-RS annotation you can use feign-jaxrs.


How to be async ?

Do not write a custom feign.Decoder!

You can use Java 8 CompletableFuture

Or the feign-hystrix provide RxJava support

Live coding

Async with ReactiveX

See code on github

Circuit Breaker

By Bidgee (Own work) CC BY-SA 3.0, via Wikimedia Commons

Live coding

Circuit Breaker with Hystrix

See code on github

With Hystrix

// Fallback implementation
CatClient fallback = () -> {
    Cat cat = new Cat("Chuck Norris's cat", CatRace.Sphynx);
    return Observable.just(Collections.singletonList(cat));
// Get Client with CircuitBreaker
CatClient client = HystrixFeign.builder()
    // ...
    .target(CatClient.class, url, fallback);
// Find All every 2 seconds
Observable.interval(2, SECONDS)
    .flatMap(i -> client.findAll()) // to Observable<List<Cat>>
    .flatMap(Observable::from) // unfold to Observable<Cat>

Incoming train ....

Download Java 9 Early Access
Can be downloaded with/without Jigsaw

Or use docker:

docker run openjdk:9 java -version

docker run maven:3-jdk-9 mvn -version

JEP 110: HTTP/2 Client

URI uri = new URI("")
HttpResponse resp = HttpRequest.create(uri)
int statusCode = resp.statusCode();
String body = resp.body(HttpResponse.asString());
System.out.printf("[%s] %s\n", statusCode, body);

Live coding

Custom feign.Client with Java 9

See code on github

Custom Client with Java 9

HttpRequest.Builder builder = HttpRequest.create(new URI(request.url()));
// Handle body
byte[] bytes = request.body();
boolean isBodyEmpty = bytes == null || bytes.length == 0;
builder = builder.body(isBodyEmpty?noBody():fromByteArray(bytes));
// Apply headers
for (Map.Entry<String, Collection&tl;String>> entry : request.headers().entrySet()) {
    String values = entry.getValue().stream().collect(Collectors.joining(", "));
    builder = builder.setHeader(entry.getKey(), values);
// Execute request
HttpResponse response = builder.method(request.method()).response();
// Build Feign response
return Response.builder()

feign.Client implementation

So why feign:

Open & active community

Simple & intuitive

Extensible, useful plugins, easy to write your own

Not opinionated


Any Question ?