OkHttp is een hoogwaardige HTTP-client voor Android en Kotlin, ontwikkeld door Square als basis voor Retrofit en andere netwerkbibliotheken. Het zorgt voor efficiënt verbindingsbeheer, ingebouwde caching en ondersteuning voor HTTP/2. Volgens Square, 2025 verwerkt OkHttp dagelijks miljarden verzoeken in applicaties over de hele wereld.
Belangrijkste punten
OkHttp is een efficiënte HTTP-client voor Java, Android en Kotlin, ontwikkeld door Square. De bibliotheek biedt een low-level API voor het uitvoeren van HTTP-verzoeken met ondersteuning voor HTTP/2, SPDY, WebSocket en automatisch herstel van verbindingen bij netwerkstoringen.
OkHttp verscheen in 2013 als antwoord op de behoefte aan een betrouwbare HTTP-client die de problemen van HttpURLConnection — gebrek aan verbindingspool, zwakke ondersteuning voor HTTP/2 en onhandige API — zou oplossen. In 2025 wordt OkHttp gebruikt op systeemniveau van Android API: OkHttp is ingebouwd in de implementatie van HttpURLConnection sinds Android 4.4 (API 19).
Volgens Google I/O 2024 verwerkt OkHttp meer dan 70% van alle HTTP-verzoeken in het Android-ecosysteem. Dit is mogelijk omdat OkHttp de transportlaag is voor Retrofit, Apollo GraphQL, Firebase en vele andere bibliotheken. Ontwikkelaars krijgen de functionaliteit van OkHttp automatisch, zonder het expliciet aan te sluiten.
De architectuur van OkHttp is gebouwd op een keten van interceptors (Interceptor chain). Elk verzoek doorloopt een reeks interceptors die Request, Response kunnen wijzigen of de uitvoering kunnen onderbreken. Deze architectuur doet denken aan het Chain of Responsibility-patroon en maakt flexibele uitbreiding van functionaliteit mogelijk.
Wanneer een applicatie een verzoek verstuurt, voert OkHttp de volgende stappen uit: lost DNS op, selecteert een verbinding uit de pool (of maakt een nieuwe), opent TLS-handshake (indien HTTPS), verstuurt het HTTP-verzoek, ontvangt het antwoord en retourneert het aan de applicatie. RealCall is een interne klasse die de volledige levenscyclus van het verzoek beheert, van creatie tot voltooiing.
OkHttp handelt automatisch omleidingen (302, 301) af, herhaalt verzoeken bij netwerkstoringen (retry), volgt het keep-alive-protocol en ondersteunt transparante gzip-compressie. De ontwikkelaar hoeft geen code te schrijven voor deze bewerkingen — OkHttp doet ze automatisch op basis van serverheaders.
HTTP/2 maakt het mogelijk om meerdere verzoeken tegelijk via een enkele TCP-verbinding te verzenden, zonder blokkering (head-of-line blocking, kenmerkend voor HTTP/1.1). OkHttp gebruikt automatisch HTTP/2 als de server dit protocol ondersteunt en schakelt transparant over naar HTTP/1.1 wanneer nodig.
Multiplexing van HTTP/2 is vooral belangrijk voor mobiele applicaties, waar de vertraging van het opzetten van een verbinding (TCP + TLS) 100–300 ms kan zijn. In plaats van 10 opeenvolgende verbindingen gebruikt OkHttp er één, waardoor de totale vertraging op typische Android-apparaten met een onstabiele verbinding met 40–60% wordt verminderd.
Interceptor is een interface met een enkele methode intercept(Chain) die Request ontvangt, acties uitvoert en Response retourneert. Interceptors zijn er in twee typen: applicatie-interceptors (toegevoegd via addInterceptor) en netwerk-interceptors (addNetworkInterceptor).
Applicatie-interceptors worden geactiveerd voordat het HTTP-verzoek wordt gevormd — ze zien de originele Request en de uiteindelijke Response na alle transformaties. Netwerk-interceptors worden geactiveerd op netwerkniveau: ze zien het verzoek na gzip-compressie, toevoeging van Content-Length-headers, omleidingen en herpogingen. Netwerk-interceptors worden niet aangeroepen als het antwoord uit de cache komt.
| Interceptortype | Toevoegmethode | Wanneer aangeroepen | Ziet cache |
|---|---|---|---|
| Application Interceptor | addInterceptor() | Voor en na verzoek | Ja |
| Network Interceptor | addNetworkInterceptor() | Op netwerkniveau | Nee |
In de praktijk lossen OkHttp-interceptors drie hoofdtaken op: autorisatie (toevoegen van Authorization-header), logging (HttpLoggingInterceptor voor foutopsporing) en herpoging (automatisch herhalen van verzoek bij netwerkstoringen). Door meerdere interceptors te combineren, kan een volledige verwerkingspijplijn worden opgebouwd zonder code te dupliceren in elke HTTP-aanroep van de applicatie.
De volgorde van toevoegen van interceptors is van belang: de Interceptor die als eerste wordt toegevoegd, wordt als eerste uitgevoerd bij binnenkomst en als laatste bij uitgang. Voor NetworkInterceptor wordt de volgorde bepaald door de netwerkstack. Aanbevolen volgorde: AuthInterceptor (voegt token toe), LoggingInterceptor (logt verzoek), RetryInterceptor (herhaalt bij storingen).
Voor het debuggen van netwerkverzoeken wordt HttpLoggingInterceptor gebruikt — een kant-en-klare interceptor van Square. Het logt de methode, URL, headers en body van verzoek en antwoord. Loggingniveaus: BASIC (methode + URL + code), HEADERS (met headers) en BODY (volledig verzoek en antwoord). BODY is nuttig tijdens ontwikkeling, maar wordt in productie uitgeschakeld om veiligheids- en prestatie redenen.
Laten we een basis GET-verzoek via OkHttp bekijken. Eerst wordt OkHttpClient gemaakt — een zwaar object dat eenmalig wordt gemaakt en hergebruikt. Vervolgens wordt een Request met URL gevormd en het verzoek wordt synchroon uitgevoerd via execute of asynchroon via enqueue.
val client = OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.build()
val request = Request.Builder()
.url("https://api.github.com/users/octocat")
.header("Accept", "application/vnd.github.v3+json")
.build()
val response = client.newCall(request).execute()
println(response.body()?.string())
Voor asynchrone uitvoering wordt de methode enqueue gebruikt, die een Callback ontvangt. OkHttp voert het verzoek uit op een achtergrondthread en retourneert het resultaat in de callback op dezelfde thread. Gebruik Handler of coroutines om over te schakelen naar de hoofdthread van Android.
client.newCall(request).enqueue(object : Callback {
override fun onFailure(
call: Call, e: IOException
) {
println("Verzoek mislukt: ${e.message}")
}
override fun onResponse(
call: Call, response: Response
) {
println(response.body()?.string())
}
})
Een aangepaste Interceptor voegt een Bearer-token toe aan elk verzoek. De interceptor controleert de aanwezigheid van de Authorization-header en als het token nog niet is ingesteld, voegt het deze toe uit de opslag. Bij een 401-reactie kan de interceptor het token vernieuwen via Authenticator.
class AuthInterceptor(
private val tokenProvider: () -> String?
) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val originalRequest = chain.request()
val token = tokenProvider.invoke()
val request = originalRequest.newBuilder()
.header("Authorization", "Bearer $token")
.build()
return chain.proceed(request)
}
}
De verbindingspool (ConnectionPool) — de belangrijkste optimalisatie van OkHttp, die het mogelijk maakt TCP-verbindingen te hergebruiken voor meerdere verzoeken. In plaats van voor elk verzoek een nieuwe socket te maken, bewaart OkHttp tot 5 inactieve verbindingen (standaard) gedurende 5 minuten, wat de vertraging voor herhaalde verzoeken naar dezelfde host met 30–70% vermindert.
Caching van antwoorden wordt geïmplementeerd via de klasse Cache. Om caching in te schakelen, volstaat het om een directory en maximale grootte op te geven in OkHttpClient.Builder. OkHttp cached automatisch GET-antwoorden volgens de Cache-Control, Expires en ETag-headers, en retourneert gecachte gegevens zonder netwerkverzoek als ze niet verlopen zijn.
val cacheDir = File(context.cacheDir, "http-cache")
val cache = Cache(cacheDir, 10L * 1024 * 1024)
val client = OkHttpClient.Builder()
.cache(cache)
.connectionPool(ConnectionPool(5, 5, TimeUnit.MINUTES))
.build()
Correcte configuratie van de pool en cache is vooral belangrijk voor applicaties met frequente verzoeken — nieuwsfeeds, chats, gegevensupdates. Zonder pool vereist elke TCP-verbinding een drieweg-handshake (SYN, SYN-ACK, ACK) en mogelijk een TLS-handshake (2–3 round-trip), wat 100–500 ms toevoegt aan elk verzoek.
OkHttp ondersteunt ook WebSocket via de klasse RealWebSocket. Een WebSocket-verbinding wordt tot stand gebracht via een HTTP-handshake (101 Switching Protocols) en schakelt vervolgens over naar een bidirectioneel protocol. OkHttp stuurt automatisch ping-frames om de verbinding in leven te houden en maakt opnieuw verbinding bij verbreking. WebSocket van OkHttp is compatibel met standaard endpoints zoals wss://echo.websocket.org.
OkHttpClient maken voor elk verzoek — de meest voorkomende fout. OkHttpClient bevat de verbindingspool, cache en threadpool. Het maken van een nieuwe instantie voor elk verzoek verspilt niet alleen geheugen, maar ontneemt ook het voordeel van hergebruik van verbindingen. OkHttpClient moet een singleton zijn via een DI-container.
Het negeren van het sluiten van Response.body() leidt tot resourcelekken. ResponseBody bevat een InputStream die na het lezen moet worden gesloten. Als body().string() of body().bytes() wordt gebruikt, sluit OkHttp de stream automatisch, maar bij het lezen van body().byteStream() of body().charStream() is een expliciete aanroep van close() in het finally-blok vereist.
Het ontbreken van timeout-afhandeling — nog een probleem. Standaard heeft OkHttp geen timeouts (connectTimeout = 10 seconden, readTimeout = 10 seconden, writeTimeout = 10 seconden). Voor mobiele applicaties met een onstabiele verbinding wordt aanbevolen om connectTimeout 15–30 seconden en readTimeout 15–30 seconden in te stellen, anders wacht de gebruiker te lang bij een zwak signaal.
Veelgestelde vragen
OkHttp is een low-level HTTP-client met handmatig beheer van Request en Response. Retrofit is een high-level wrapper met annotaties. OkHttp wordt gebruikt als transport voor Retrofit, maar kan ook zelfstandig werken zonder extra bibliotheken.
OkHttp gebruikt SSLSocketFactory voor TLS-handshake. De bibliotheek ondersteunt CertificatePinner voor het vastpinnen van certificaten (Certificate Pinning), TrustManager voor aangepaste validatie en HostnameVerifier voor het controleren van de hostnaam tegen het certificaat.
Synchrone verzoeken gooien IOException bij netwerkproblemen. Asynchrone verzoeken krijgen een onFailure-aanroep met IOException. Voor HTTP-fouten (4xx, 5xx) wordt het antwoord als succesvol beschouwd — de foutcode wordt gecontroleerd via response.isSuccessful().
Ja, OkHttp heeft ingebouwde ondersteuning voor WebSocket via de klassen WebSocket en WebSocketListener. Na het tot stand brengen van de verbinding maakt WebSocket real-time verzenden en ontvangen van berichten mogelijk zonder herhaalde HTTP-verzoeken.
Schakel automatische omleidingen uit via followRedirects(false) en followSslRedirects(false) in OkHttpClient.Builder. Dit is handig wanneer u een omleiding handmatig moet afhandelen, bijvoorbeeld om een token uit de omleidings-URL te extraheren.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook