Igor Laborie
whoami
whois feign
https://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
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 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>
.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 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()
.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