Fallbacks are known values, which you return when there's an error invoking an http method.
For example, you can return a cached result as opposed to raising an error to the caller. To use
this feature, pass a safe implementation of your target interface as the last parameter to `HystrixFeign.Builder.target`.
Here's an example:
```java
// When dealing with fallbacks, it is less tedious to keep interfaces small.
interface GitHub {
@RequestLine("GET /repos/{owner}/{repo}/contributors")
List<String> contributors(@Param("owner") String owner, @Param("repo") String repo);
}
// This instance will be invoked if there are errors of any kind.
GitHub fallback = (owner, repo) -> {
if (owner.equals("Netflix") && repo.equals("feign")) {
return Arrays.asList("stuarthendren"); // inspired this approach!
} else {
return Collections.emptyList();
}
};
GitHub github = HystrixFeign.builder()
...
.target(GitHub.class, "https://api.github.com", fallback);
```
Credit to the idea goes to @stuarthendren!
This adds the `Feign.Builder.decode404()` flag which indicates decoders
should process responses with 404 status. It also changes all
first-party decoders (like gson) to return well-known empty values by
default. Further customization is possible by wrapping or creating a
custom decoder.
Prior to this change, we used custom invocation handlers as the way to
add fallback values based on exception or return status. `feign-hystrix`
uses this to return `HystrixCommand<X>`, but the general pattern applies
to anything that has a type representing both success and failure, such
as `Try<X>` or `Observable<X>`.
As we define it here, 404 status is not a retry or fallback policy, it
is just empty semantics. By limiting Feign's special processing to 404,
we gain a lot with very little supporting code.
If instead we opened all codes, Feign could easily turn bad request,
redirect, or server errors silently to null. This sort of configuration
issue is hard to troubleshoot. 404 -> empty is a very safe policy vs
all codes.
Moreover, we don't create a cliff, where folks seeking fallback policy
eventually realize they can't if only given a response code. Fallback
systems like Hystrix address exceptions that occur before or in lieu of
a response. By special-casing 404, we avoid a slippery slope of half-
implementing Hystrix.
Finally, 404 handling has been commonly requested: it has a clear use-
case, and through that value. This design supports that without breaking
compatibility, or impacting existing integrations such as Hystrix or
Ribbon.
See #238#287
In unsuccessful scenarios, such as redirects, error handling converts a
`Response` into an exception. When a user defines a return type as
`Response`, we can assume they will want access to things like headers
even in an error scenario.
See #249
Before this change, apis that follow patterns across a service could
only be modeled by copy/paste/find/replace. Especially with a large
count, this is monotonous and error prone.
This change introduces support for base apis via single-inheritance
interfaces. Users ensure their target interface bind any type variables
and as a result have little effort to create boilerplate apis.
Ex.
```java
@Headers("Accept: application/json")
interface BaseApi<V> {
@RequestLine("GET /api/{key}")
V get(@Param("key") String);
@RequestLine("GET /api")
List<V> list();
@Headers("Content-Type: application/json")
@RequestLine("PUT /api/{key}")
void put(@Param("key") String, V value);
}
interface FooApi extends BaseApi<Foo> { }
interface BarApi extends BaseApi<Bar> { }
```
closes#133
Previously, the Retryer instance provided to the Builder was simply reused, but the instance keeps per-request state, causing repeatable requests to stop being retried. Fixes#236
Before, LBClients were created for each request, which led to issues
such as #182. Moreover, a user could not avoid using Ribbon's static
factories. Adding LBClientFactory allows users to control how Ribbon
resources are created.
Files had various formatting differences, as did pull requests. Rather than
create our own style, this inherits and requires the well documented Google
Java Style.
Feign has `MethodMetadata.bodyType()`, but never passed it to encoders.
Encoders that register type adapters need to do so based on the
interface desired as opposed to the implementation class. This change
breaks api compatibility for < 8.x, by requiring an additional arg
on `Encoder.encode`.
see https://github.com/square/retrofit/issues/713
Dagger 1.x and 2.x are incompatible. Rather than choose one over the
other, this change removes Dagger completely. Users can now choose any
injector, constructing Feign via its Builder.
This change also drops support for javax.inject.Named, which has
been replaced by feign.Param.
see #120
Parameters annotated with `Param` expand based on their `toString`. By
specifying a custom `Param.Expander`, users can control this behavior,
for example formatting dates.
```java
@RequestLine("GET /?since={date}") Result list(@Param(value = "date", expander = DateToMillis.class) Date date);
```
Closes#122
Feign 8.x will no longer support Dagger, nor interfaces annotated with `javax.inject.@Named`. Users must migrate from `javax.inject.@Named` to `feign.@Param` via Feign v7.1+ before attempting to update to Feign 8.0.
For example, the following uses `@Param` as opposed to `@Named` to annotate template parameters.
```java
interface GitHub {
@RequestLine("GET /repos/{owner}/{repo}/contributors")
List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);
}
```
Adds a new "slf4j" module. A few methods in Logger are now protected rather
than package protected to allow access by Logger subclasses that aren't
inner classes of Logger.
Request/Response/RequestTemplate are now fundamentally based on a byte[] body field.
For Request/RequestTemplate, if a charset is provided, it can be treated as text.
For many users of the library, the change should barely be noticeable, as the methods that
were changed were mostly used internally.
There were some non-backwards-compatible signature changes that require a
major version bump, however.
commit 34eb5751c760cf1f11cdbab920d6a3a1c6f06640
Author: Matt Hurne <matt@thehurnes.com>
Date: Tue Oct 15 15:54:20 2013 -0400
Remove unnecessary defensive close of Reader
commit 38e51606750517d4a52571c408190e614a4a4834
Author: Matt Hurne <matt@thehurnes.com>
Date: Tue Oct 8 13:59:35 2013 -0400
Replace wildcard import with individual imports
commit cc845814ea677ba5920caf5a7a914010623caf1e
Author: Matt Hurne <matt@thehurnes.com>
Date: Tue Oct 8 13:55:37 2013 -0400
Revert GitHub example to use JacksonDecoder rather than JacksonModule now that JacksonDecoder behaves sensibly with its default ObjectMapper
commit 8b9638261afe2549c3a43238ee1b66d044f969f4
Author: Matt Hurne <matt@thehurnes.com>
Date: Tue Oct 8 13:52:45 2013 -0400
Configure default ObjectMapper used by JacksonEncoder and JacksonDecoder with sensible overrides of default behaviors
commit 0f275bf7574b66c20a0e6aefe0140f599638992f
Author: Matt Hurne <matt@thehurnes.com>
Date: Tue Oct 8 13:18:26 2013 -0400
Unwrap RuntimeJsonMappingExceptions caught in JacksonDecoder, since they are only ever used to wrap JsonMappingExceptions, which are IOExceptions.
commit 1b6995260a5727796e388bbb0b6c88b65e182415
Author: Matt Hurne <matt@thehurnes.com>
Date: Tue Oct 8 13:09:44 2013 -0400
Update Jackson integration README
commit add4007a59559e7b4e2accfa0b0a0215bab62cef
Author: Matt Hurne <matt@thehurnes.com>
Date: Tue Oct 8 13:07:35 2013 -0400
Update CHANGES and README to reflect addition of Jackson integration
commit 86c0fcfc704b1b8d03e5eaf69c608fc2761d617b
Author: Matt Hurne <matt@thehurnes.com>
Date: Tue Oct 8 12:11:56 2013 -0400
Update Jackson GitHub example to make use of JacksonModule, and to avoid the need for Jackson annotations
commit 1552b3f8239636da0f27ace3c7b42038536e5caf
Author: Matt Hurne <matt@thehurnes.com>
Date: Tue Oct 8 12:05:56 2013 -0400
Replace wildcard import with individual imports
commit 0b7cfd08516dfbf66f1a69263ed456f2c0671c76
Author: Matt Hurne <matt@thehurnes.com>
Date: Tue Oct 8 11:01:11 2013 -0400
Initial implementation of Jackson codec
This new codec may be used as an alternative to Gson.
commit 94027ec3319f5145c0e18ef472d8e928e97a9527
Author: Matt Hurne <matt@thehurnes.com>
Date: Tue Oct 8 08:31:14 2013 -0400
Improve EncodeException and DecodeException Javadoc comments