Retrofit is a type-safe HTTP client for Android and Java, used for making API calls easier and much more manageable. In this article, we’ll delve into how to add headers and interceptors when making calls with Retrofit in Kotlin.
Introduction to Retrofit
Retrofit simplifies HTTP communication by transforming your HTTP API into a Java interface, adding convenience with the use of annotations for converting JSON responses into Java/Kotlin objects.
Setting Up Retrofit
To use Retrofit in a Kotlin project, first, you need to add the necessary dependencies. Typically, this will include Retrofit itself, a JSON parser like Gson, and logging utilities:
dependencies {
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0'
}
Adding Headers in Retrofit
In many use cases, APIs will require you to send headers for authentication or content-type definitions. You can statically add headers by annotating your API interface methods with @Headers:
interface ApiService {
@Headers("Accept: application/json")
@GET("/users")
suspend fun getUsers(): List<User>
}
For dynamic headers, you should use the @Header annotation in the method signature. This approach is suitable when you want to pass headers at runtime:
interface ApiService {
@GET("/users")
suspend fun getUsers(@Header("Authorization") token: String): List<User>
}
Interceptors in Retrofit
Interceptors are a great way to manipulate requests and responses. They're widely used for adding request-level customization like logging, modifying headers, and error handling. There's a built-in way in OkHttp, a network library that underpins Retrofit, to declare interceptors.
Example of Adding an Interceptor
val interceptor = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
val client = OkHttpClient.Builder()
.addInterceptor(interceptor)
.build()
val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com")
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build()
In the example above, the HttpLoggingInterceptor is used to log the body of HTTP communication. This is especially helpful during development for tracking request parameters and server responses.
Adding a Custom Interceptor
Creating a custom interceptor can be done by implementing the Interceptor interface. Here is an example on how to add a token to every request:
class AuthInterceptor(private val authToken: String) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request().newBuilder()
.addHeader("Authorization", "Bearer $authToken")
.build()
return chain.proceed(request)
}
}
val authInterceptor = AuthInterceptor("your-auth-token")
val authClient = OkHttpClient.Builder()
.addInterceptor(authInterceptor)
.build()
By adding the AuthInterceptor, you streamline authentication headers across requests.
Conclusion
Incorporating headers and interceptors in Retrofit enhances manageability and reusability in your project setup. It allows for adding essential request data such as authentication tokens, transforming requests and responses, and implementing logging for debugging purposes. With these tools, you've additional means to handle complex scenarios and optimize communications with your API efficiently.
Real-world applications extensively benefit from these techniques. Practice by setting up a sample project or implementing these tactics in your existing projects to fully understand their dynamic potential.