Retrofit — Add Custom Request Header

You’ve already learned how to integrate authentication with Retrofit, how to pass multiple query parameter values for the same identifier. Additionally, if you read the previously published articles within this series, you know how to create your own custom response converter and register it into the Retrofit instance.

This tutorial shows you how to add custom headers to your requests by using the @Header annotation within your interface definition or by intercepting the request and add defined header fields with their values.

Retrofit Series Overview

  1. Callbacks (Coming soon)
  2. Annotations (Coming soon)
  3. Fluent Interface with Builders (Coming soon)

Define Custom Request Headers

Retrofit provides two options to define HTTP request header fields: static and dynamic. Static headers can’t be changed for different requests. The header’s key and value are fixed and initiated with the app startup.

In contrast, dynamic headers must be set for each request.

Static Request Header

The first option to add a static header is to define the header and respective value for your API method as an annotation. The header gets automatically added by Retrofit for every request using this method. The annotation can be either key-value-pair as one string or as a list of strings. Let's face two specific examples which illustrate the definition options:

Retrofit 2

public interface UserService {  
    @Headers("Cache-Control: max-age=640000")
    @GET("/tasks")
    Call<List<Task>> getTasks();
}

Retrofit 1.9

public interface UserService {  
    @Headers("Cache-Control: max-age=640000")
    @GET("/tasks")
    List<Task> getTasks();
}

The example above shows the key-value-definition for the static header. Further, you can pass multiple key-value-strings as a list encapsulated in curly brackets {} to the @Headers annotation.

Retrofit 2

public interface UserService {  
    @Headers({
        "Accept: application/vnd.yourapi.v1.full+json",
        "User-Agent: Your-App-Name"
    })
    @GET("/tasks/{task_id}")
    Call<Task> getTask(@Path("task_id") long taskId);
}

Retrofit 1.9

public interface UserService {  
    @Headers({
        "Accept: application/vnd.yourapi.v1.full+json",
        "User-Agent: Your-App-Name"
    })
    @GET("/tasks/{task_id}")
    Task getTask(@Path("task_id") long taskId);
}

Additionally, you can define static headers via the intercept method of Retrofits RequestInterceptor (customized implementation of the Interceptor interface in Retrofit 2). We already used the RequestInterceptor within the previous tutorials (Basic and Token Auth, OAuth) and of course you can enhance it by setting header fields.

Retrofit 2

In Retrofit 2, you need to intercept the request on the network layer provided by OkHttp.

OkHttpClient.Builder httpClient = new OkHttpClient.Builder();  
httpClient.addInterceptor(new Interceptor() {  
    @Override
    public Response intercept(Interceptor.Chain chain) throws IOException {
        Request original = chain.request();

        Request request = original.newBuilder()
            .header("User-Agent", "Your-App-Name")
            .header("Accept", "application/vnd.yourapi.v1.full+json")
            .method(original.method(), original.body())
            .build();

        return chain.proceed(request);
    }
}

OkHttpClient client = httpClient.build();  
Retrofit retrofit = new Retrofit.Builder()  
    .baseUrl(API_BASE_URL)
    .addConverterFactory(GsonConverterFactory.create())
    .client(client)
    .build();

Retrofit 1.9

RequestInterceptor requestInterceptor = new RequestInterceptor() {  
    @Override
    public void intercept(RequestFacade request) {
        request.addHeader("User-Agent", "Your-App-Name");
        request.addHeader("Accept", "application/vnd.yourapi.v1.full+json");
    }
};

RestAdapter restAdapter = new RestAdapter.Builder()  
    .setEndpoint("https://api.github.com")
    .setRequestInterceptor(requestInterceptor)
    .build();

As you can see, the examples above set the User-Agent and Accept header fields with respective values. These values are passed with every request which is executed using the RestAdapter (Retrofit in Retrofit 2) and the integrated RequestInterceptor (Interceptor in Retrofit 2).

Dynamic Header

A more customizable approach are dynamic headers. A dynamic header is passed like a parameter to the method. The provided parameter value gets mapped by Retrofit before executing the request. Let's look at the code example:

Retrofit 2

public interface UserService {  
    @GET("/tasks")
    Call<List<Task>> getTasks(@Header("Content-Range") String contentRange);
}

Retrofit 1.9

public interface UserService {  
    @GET("/tasks")
    List<Task> getTasks(@Header("Content-Range") String contentRange);
}

Define dynamic headers where you might pass different values for each request. The example illustrates the dynamic header with Content-Range definition.

No Header Override in Retrofit 1

Remember: Retrofit doesn't override header definitions with the same name. Every defined header is added to the request.

That's it. Retrofit simplifies header manipulation and allows to simply change them for separated requests when necessary.

In case things went south, give us a shot on twitter @futurestud_io.

Override Existing Headers in Retrofit 2

As opposed to Retrofit v1, you can override the values of existing header fields. You can override the values within the Interceptor implementation passed to the used OkHttp client. The Request.Builder offers two methods to add headers:

  1. .header(key, value): overrides the respective header key with value if there is already an existing header identified by key
  2. .addHeader(key, value): adds the respective header key and value even if there is an existing header field with the same key

Summary

In this tutorial you've learned how you can add custom request header to your Retrofit requests. You can add headers dynamically or in a static way.

If you've any questions, let us know on Twitter @futurestud_io or in the comment section below.

Enjoy coding & make it rock!


Additional Resources


Explore the Library

Find interesting tutorials and solutions for your problems.

Miscellaneous