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
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 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
POC implementation with Reactor core 3 on my feign-reactor
// 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);
java.net.http, See The New JDK HTTP Client API Room 9, Thursday from 09:30 til 10:30, by Michael McMahon
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