Igor Laborie
whoamiwhois feignhttps://github.com/OpenFeign/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 javax.ws.rs
Most Java applications require a persistent class representing felines.
Most Java applications require a microservice for felines.
curl http://cats/swagger
Run with: docker run -p 8080:8080 ilaborie/cats-microservice
See code on github
Current lastest release: 9.3.1
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-core</artifactId><version>${feign.version}</version></dependency><dependency><groupId>io.github.openfeign</>roupId><artifactId>feign-gson</artifactId><version>${feign.version}</version></dependency><dependency><groupId>io.github.openfeign</>roupId><artifactId>feign-slf4j</artifactId><version>${feign.version}</version></dependency>
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);}
CatClient client = Feign.builder()// Create request body.encoder(new GsonEncoder())// Transform response body.decoder(new GsonDecoder())// Add custom header.requestInterceptor(template -> template.header("Date", Instant.now().toString()))// Tips: debug lite.requestInterceptor(System.out::println)// Tips: debug with logger.logLevel(Logger.Level.FULL).logger(new Slf4jLogger()).target(CatClient.class, url);
feign-jaxb,
jackson-jaxb or
feign-sax (decoder
only)
No White/Dark Magic
The
java.lang.reflect.Proxy
allow you to dynamically implement the interface.
Use the
java.net.HttpURLConnection
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.
Do not write a custom feign.Decoder!
You can use Java 8 CompletableFuture
Or the feign-hystrix
provide RxJava support


// Fallback implementationCatClient fallback = () -> {Cat cat = new Cat("Chuck Norris's cat", CatRace.Sphynx);return Observable.just(Collections.singletonList(cat));};// Get Client with CircuitBreakerCatClient client = HystrixFeign.builder()// ....target(CatClient.class, url, fallback);// Find All every 2 secondsObservable.interval(2, SECONDS).flatMap(i -> client.findAll()) // to Observable<List<Cat>>.flatMap(Observable::from) // unfold to Observable<Cat>.forEach(System.out::println);
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
URI uri = new URI("http://127.0.0.1:8080/hello")HttpResponse resp = HttpRequest.create(uri).GET().response();int statusCode = resp.statusCode();String body = resp.body(HttpResponse.asString());System.out.printf("[%s] %s\n", statusCode, body);
feign.Client with
HttpRequest.Builder builder = HttpRequest.create(new URI(request.url()));// Handle bodybyte[] bytes = request.body();boolean isBodyEmpty = bytes == null || bytes.length == 0;builder = builder.body(isBodyEmpty?noBody():fromByteArray(bytes));// Apply headersfor (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 requestHttpResponse response = builder.method(request.method()).response();// Build Feign responsereturn Response.builder().status(response.statusCode()).headers(mapList2MapCollection(response.headers().map())).body(response.body(HttpResponse.asByteArray())).build();
feign.Client implementationfeign-httpclient
feign-okhttp
HTTP/2 & caching support
feign-ribbon
Load balancing support
Open & active community
Simple & intuitive
Extensible, useful plugins, easy to write your own
Not opinionated