Netflix/denominator — pull request #159 by adriancole (2013-06-03 20:00:43+00:00)
Title: Feign makes developing against apis that feign restfulness a little bit easier

This pull request introduces Feign, a java to http client binder inspired by [Dagger](https://github.com/square/dagger), [Retrofit](https://github.com/square/retrofit), [jclouds](https://github.com/jclouds/jclouds), and [JAXRS-2.0](https://jax-rs-spec.java.net/nonav/2.0/apidocs/index.html).

### Why Feign and not X?

Restful apis have normalized patterns, formats, and idempotency constraints. Restful apis can be defined in JAXRS annotations and magically turned into implementations.

Feign aims to make binding java to http apis that feign restfulness easy, too! Using Feign's regex and overridable codecs, you can write clients for any http service using the same programming model. Yes.. even SOAP!. If you are lucky enough to work with a HATEOAS api, Feign supports advanced restful patterns such as URL discovery and filtering to make that easier, too. Basically, whether the api is restful or feigns restfulness, you should be able to write a client for it using Feign.

Feign works by processing annotations into a templatized request. Just before sending it off, arguments are applied to these templates in a straightforward fashion. While this limits Feign to only supporting text-based apis, it dramatically simplified system aspects such as replaying requests. It is also stupid easy to unit test your conversions knowing this.

### Basics

Usage typically looks like this, an adaptation of the [canonical Retrofit sample](https://github.com/square/retrofit/blob/master/retrofit-samples/github-client/src/main/java/com/example/retrofit/GitHubClient.java).

```java
interface GitHub {
@GET
@Path("/repos/{owner}/{repo}/contributors")
@Regex(pattern = "\"login\":\"([^\"]+)\".*?\"contributions\":([0-9]+)")
Map contributors(@PathParam("owner") String owner, @PathParam("repo") String repo);
}

public static void main(String... args) {

GitHub github = Feign.create(GitHub.class, "https://api.github.com");

// Fetch and print a list of the contributors to this library.
Map contributors = github.contributors("netflix", "denominator");
for (Entry contributor : contributors.entrySet()) {
System.out.println(contributor.getKey() + " (" + contributor.getValue() + ")");
}
}
```

The `@Regex` expression above defines how to decode the response. You can decode reges into types including `String`, `List`, `Map`, `Multimap`, and `Table`. If you don't like RegEx, you can use your favorite marshaling library, wired up as `Decoder`.

Feign can produce multiple api interfaces. These are defined as `Target` (default `HardCodedTarget`), which allow for dynamic discovery and decoration of requests prior to execution.

For example, the following pattern might decorate each request with the current url and auth token from the identity service.

```java
CloudDNS cloudDNS = Feign.create().newInstance(new CloudIdentityTarget(user, apiKey));
```
### Advanced usage and Dagger
Feign can be directly wired into Dagger as well. This allows you to take advantage of `Singleton`, `Lazy`, and other handy features, as well use Dagger for config as opposed to writing builders. Taking the example above, I could wire up like so..

```java
@Module(injects = Rackspace.class, complete = false)
static class RackspaceModule {
...
@Provides
@Singleton
CloudDNS cloudDNS(Feign feign, CloudDNSTarget target) {
return feign.newInstance(target);
}
}

static class CloudDNSTarget implements Target {
private final Lazy lazyUrlAndToken;

@Inject
CloudDNSTarget(Lazy lazyUrlAndToken) {
this.lazyUrlAndToken = lazyUrlAndToken;
}
...
@Override
public String url() {
return lazyUrlAndToken.get().getUrl();
}

@Override
public Request apply(RequestTemplate input) {
input.insert(0, urlAndToken.get().getUrl()));
input.header("X-Auth-Token", urlAndToken.get().getToken());
return input.request();
}
}
```