Retrofit: My new HTTP client of choice

There’s no shortage of options for Java developers when dealing with HTTP connections client-side. Java itself brings facilities to work with HTTP, but they are very low level and inconvenient as is Apache’s HttpClient. I’ve been using some more high-level implementations in the past, Spring’s RestTemplate is often a good fit, the same goes for the client implementation of Jersey.

Recently I found another nice library called Retrofit, after some playing around with it I think it will be my new HTTP client library of choice.

So what’s so special?

Retrofit will turn HTTP requests into Java-APIs. You’ll define a Java interface and map its methods to HTTP requests. Retrofit will then generate the code that will interact with the server. With no further configuration this looks like this:

public interface GithubService {
 
  @GET("users/{user}/repos")
  Call listRepos(@Path("user") String username);
}

Then in your code, you’ll use it like this:

Retrofit retrofit = new Retrofit.Builder()
  .baseUrl("https://api.github.com")
  .build();
GithubService service = retrofit.create(GithubEndpoint.class);
Call<ResponseBody> call = service.listRepos("dnno");
Response<ResponseBody> response = call.execute();

The response object will give you access to data connected to the http response.

Customizing the Java API

Retrofit builds upon OkHttp and will as a default use its types RequestBody and ResponseBody. However, Retrofit comes with an option to use converters, which will give you the possibility to map requests and responses to Java objects. I’m used to Jackson, so I tried using the Jackson converter. All you need to do is create a service that uses a pojo instead of the default OkHttp types:

public interface JacksonGithubService {
 
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String username);
}

Then you’ll setup Retrofit to use the Jackson converter and access your service like this:

Retrofit retrofit = new Retrofit.Builder()
  .baseUrl("https://api.github.com")
  .addConverterFactory(JacksonConverterFactory.create())
  .build();
 
JacksonGithubService service = retrofit.create(JacksonGithubService.class);
 
Call<List<Repo>> call = service.listRepos("dnno");
Response<List<Repo>> response = call.execute();

If you want to use a custom ObjectMapper, you can pass one to the converter factory. There are other converters (e.g. for Google’s Gson) and you can write custom converters as well.

Asynchronous request processing

So far, I’ve used synchronous requests by calling the execute() method. Retrofit also provides a way to make asynchronous requests:

call.enqueue(new Callback<Repo>() {
 
  public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
    // process successfull response
  }
 
  public void onFailure(Call<List<Repo>> call, Response<List<Repo>> response) {
    // process error response
  }
}

What else?

Integration into a project is easy enough, you just add it as a Maven/Gradle dependency.

<dependency>
  <groupId>com.squareup.retrofit2</groupId>
  <artifactId>retrofit</artifactId>
  <version>2.0.2</version>
</dependency>

There’s plenty of online resources so in case of a problem, it should be easy to get help as well. I’ve created a sample project with a few tests that demonstrate the usage further, it’s available on Github – go ahead and take a look if you like.

One thought on “Retrofit: My new HTTP client of choice

Leave a Reply