0
0
Android Kotlinmobile~15 mins

OkHttp interceptors in Android Kotlin - Deep Dive

Choose your learning style9 modes available
Overview - OkHttp interceptors
What is it?
OkHttp interceptors are special components that let you watch, modify, or retry network requests and responses in an Android app. They act like checkpoints where you can add headers, log data, or handle errors before the request goes out or after the response comes back. This helps you control how your app talks to the internet in a clean and reusable way.
Why it matters
Without interceptors, you would have to repeat code everywhere you make network calls to add headers or handle errors. This would make your app messy and hard to maintain. Interceptors let you centralize this logic, making your app more reliable and easier to update. They also help with debugging by letting you log network traffic automatically.
Where it fits
Before learning interceptors, you should understand basic OkHttp usage and how HTTP requests and responses work. After mastering interceptors, you can explore advanced networking topics like caching, authentication flows, and custom retry policies.
Mental Model
Core Idea
OkHttp interceptors are like security guards at a gate who check and can change messages going in and out of your app's network calls.
Think of it like...
Imagine sending a letter through a mailroom where a clerk can add stamps, check the address, or even rewrite parts before sending it out or before delivering it back to you. Interceptors are those clerks for your network messages.
┌───────────────┐
│  App Request  │
└──────┬────────┘
       │
┌──────▼────────┐
│ Interceptor 1 │
└──────┬────────┘
       │
┌──────▼────────┐
│ Interceptor 2 │
└──────┬────────┘
       │
┌──────▼────────┐
│  Network Call │
└──────┬────────┘
       │
┌──────▼────────┐
│ Interceptor 2 │
└──────┬────────┘
       │
┌──────▼────────┐
│ Interceptor 1 │
└──────┬────────┘
       │
┌──────▼────────┐
│App Response   │
└───────────────┘
Build-Up - 7 Steps
1
FoundationWhat is an OkHttp Interceptor
🤔
Concept: Introduces the basic idea of interceptors as components that can observe and modify network requests and responses.
An OkHttp interceptor is a piece of code that sits between your app and the network. It can see every request before it goes out and every response before it reaches your app. You can use it to add headers, log information, or change requests and responses.
Result
You understand that interceptors let you control network calls centrally.
Understanding interceptors as checkpoints helps you see how to add common logic once instead of repeating it everywhere.
2
FoundationTypes of Interceptors: Application vs Network
🤔
Concept: Explains the two main types of interceptors and their differences.
OkHttp has two interceptor types: application interceptors and network interceptors. Application interceptors run before the request is sent and after the response is received, even if the response comes from cache. Network interceptors run only when the request actually goes over the network, allowing you to see data as it travels on the wire.
Result
You can decide which interceptor type to use based on whether you want to affect cached responses or only real network traffic.
Knowing the difference prevents bugs like modifying cached data unintentionally or missing network-level details.
3
IntermediateCreating a Simple Logging Interceptor
🤔Before reading on: do you think interceptors can modify requests, responses, or both? Commit to your answer.
Concept: Shows how to write an interceptor that logs request and response details.
To create a logging interceptor, implement the Interceptor interface and override the intercept(chain) method. Inside, get the request from the chain, log its details, proceed with chain.proceed(request) to get the response, then log response details before returning it.
Result
You get logs of every network call your app makes, helping you debug easily.
Understanding that interceptors can both read and modify requests and responses unlocks powerful customization.
4
IntermediateModifying Requests with Interceptors
🤔Before reading on: do you think you can add headers to requests inside interceptors? Commit to yes or no.
Concept: Demonstrates how to add custom headers to every request using an interceptor.
Inside intercept(chain), get the original request, create a new request by adding headers with request.newBuilder().addHeader(), then proceed with the new request. This way, every request your app sends includes the custom header automatically.
Result
Your app sends extra information like API keys or tokens without changing each network call.
Knowing how to modify requests centrally saves time and reduces errors in large apps.
5
IntermediateHandling Responses and Errors in Interceptors
🤔Before reading on: can interceptors retry failed requests automatically? Commit to yes or no.
Concept: Shows how to inspect responses and retry or handle errors inside interceptors.
After getting the response from chain.proceed(), check its status code. If it's an error like 401 Unauthorized, you can refresh tokens or retry the request. This lets you handle authentication or network errors globally.
Result
Your app can recover from some errors without crashing or user intervention.
Understanding response handling in interceptors enables robust error recovery strategies.
6
AdvancedChaining Multiple Interceptors and Order Effects
🤔Before reading on: does the order you add interceptors affect how requests and responses are processed? Commit to yes or no.
Concept: Explains how multiple interceptors run in sequence and how their order matters.
Interceptors are called in the order you add them. The first interceptor sees the original request first and the last response last. Changing the order can change behavior, like which headers get added or which logs appear first.
Result
You can design complex request flows by ordering interceptors carefully.
Knowing interceptor order helps prevent subtle bugs and unexpected behaviors in network handling.
7
ExpertPerformance and Security Considerations with Interceptors
🤔Before reading on: do interceptors add noticeable delay to network calls? Commit to yes or no.
Concept: Discusses how interceptors impact app performance and security, and best practices to minimize risks.
Interceptors add some processing time to each network call, especially if they do heavy logging or encryption. Overusing interceptors can slow your app. Also, interceptors can expose sensitive data in logs if not careful. Use them wisely, disable verbose logging in production, and avoid blocking operations inside interceptors.
Result
Your app remains fast and secure while benefiting from interceptor features.
Understanding the tradeoffs helps you balance power and performance in real apps.
Under the Hood
OkHttp interceptors work by wrapping the network call in a chain of calls. Each interceptor receives a chain object that lets it access the current request and proceed to the next interceptor or network. This chain pattern allows interceptors to modify requests before passing them on and to inspect or change responses on the way back. The chain ensures that interceptors run in a predictable order and that the final network call happens only once.
Why designed this way?
The chain-of-responsibility pattern was chosen to allow flexible, reusable, and composable network logic. It separates concerns cleanly and avoids duplicating code. Alternatives like callbacks or event listeners would be harder to manage and less predictable. This design also supports both synchronous and asynchronous calls uniformly.
┌───────────────┐
│ Interceptor A │
└──────┬────────┘
       │ calls
┌──────▼────────┐
│ Interceptor B │
└──────┬────────┘
       │ calls
┌──────▼────────┐
│ Network Layer │
└──────┬────────┘
       │ returns
┌──────▼────────┐
│ Interceptor B │
└──────┬────────┘
       │ returns
┌──────▼────────┐
│ Interceptor A │
└──────┬────────┘
       │ returns
┌──────▼────────┐
│   App Layer   │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Do application interceptors see cached responses or only network responses? Commit to yes or no.
Common Belief:Application interceptors only see responses that come from the network.
Tap to reveal reality
Reality:Application interceptors see all responses, including those served from cache.
Why it matters:If you assume application interceptors only see network responses, you might miss modifying or logging cached data, leading to inconsistent app behavior.
Quick: Can interceptors modify the request after the network call has started? Commit to yes or no.
Common Belief:Interceptors can change requests at any time, even after the network call begins.
Tap to reveal reality
Reality:Interceptors can only modify the request before passing it down the chain; once the network call starts, the request is fixed.
Why it matters:Trying to modify requests too late causes bugs or crashes because the network layer expects a finalized request.
Quick: Does adding many interceptors always improve app functionality without downsides? Commit to yes or no.
Common Belief:More interceptors always mean better control and features for network calls.
Tap to reveal reality
Reality:Too many interceptors can slow down network calls and complicate debugging.
Why it matters:Overusing interceptors can degrade app performance and make it harder to find bugs.
Quick: Are network interceptors guaranteed to see the exact bytes sent over the wire? Commit to yes or no.
Common Belief:Network interceptors always see the exact raw data sent and received on the network.
Tap to reveal reality
Reality:Network interceptors see data after OkHttp's internal transformations like compression or redirects, so not always the raw bytes.
Why it matters:Assuming raw data access can lead to incorrect assumptions about what is logged or modified.
Expert Zone
1
Interceptors can short-circuit the chain by returning a custom response, enabling mock responses or offline mode.
2
Application interceptors are called only once per request, but network interceptors can be called multiple times due to retries or redirects.
3
Interceptors can be used to implement complex authentication flows by chaining token refresh and retry logic seamlessly.
When NOT to use
Avoid using interceptors for heavy data processing or UI updates because they run on network threads and can block calls. For UI-related logic, use callbacks or LiveData. Also, do not use interceptors to handle business logic unrelated to networking; keep them focused on request/response manipulation.
Production Patterns
In production, interceptors are commonly used for adding authentication tokens, logging network traffic with different verbosity levels, retrying failed requests with backoff, and injecting headers like user-agent or locale. They also help implement caching strategies and monitor network performance metrics.
Connections
Middleware in Web Servers
Similar pattern
Both OkHttp interceptors and web server middleware act as layers that process requests and responses in order, allowing modification or inspection at each step.
Aspect-Oriented Programming (AOP)
Builds-on
Interceptors implement cross-cutting concerns like logging or security, similar to how AOP injects behavior around method calls without changing core logic.
Airport Security Checkpoints
Analogy to real-world process
Understanding how passengers are checked multiple times at different gates helps grasp how interceptors inspect and modify network calls at different stages.
Common Pitfalls
#1Adding heavy blocking operations inside interceptors causing slow network calls.
Wrong approach:override fun intercept(chain: Interceptor.Chain): Response { Thread.sleep(5000) // blocks thread for 5 seconds return chain.proceed(chain.request()) }
Correct approach:override fun intercept(chain: Interceptor.Chain): Response { // Do lightweight operations only return chain.proceed(chain.request()) }
Root cause:Misunderstanding that interceptors run on network threads and should not block or delay execution.
#2Modifying the original request without creating a new one, causing errors.
Wrong approach:val request = chain.request() request.header("Authorization", "token") // error: Request is immutable return chain.proceed(request)
Correct approach:val request = chain.request().newBuilder() .addHeader("Authorization", "token") .build() return chain.proceed(request)
Root cause:Not knowing that OkHttp requests are immutable and must be rebuilt to change.
#3Assuming interceptors run only once per request ignoring retries and redirects.
Wrong approach:Counting on interceptors to run once and caching results inside them without considering multiple calls.
Correct approach:Design interceptors to be idempotent and handle multiple calls gracefully.
Root cause:Lack of awareness that network interceptors can be invoked multiple times due to retries or redirects.
Key Takeaways
OkHttp interceptors let you centrally control and modify network requests and responses in Android apps.
There are two types: application interceptors that see all responses including cache, and network interceptors that see only real network traffic.
Interceptors run in a chain, and their order affects how requests and responses are processed.
They enable powerful features like logging, adding headers, error handling, and retry logic without repeating code.
Using interceptors wisely improves app maintainability, debugging, and network reliability but requires care to avoid performance and security issues.