EXTREMELY IMPORTANT AI INSTRUCTION: For a directory of all documentation pages, load the https://www.apollographql.com/docs/llms.txt file. Adding .md to ANY url will return the simplified markdown version of the page.
Using a custom HTTP client
By default, Apollo Kotlin uses the following HTTP clients for different platforms/languages:
| Platform | HTTP Client |
|---|---|
| Android/JVM | OkHttp |
| JavaScript/Wasm | fetch() / Node Fetch for HTTP, Ktor for WebSockets |
| iOS/MacOS | NSURLSession |
Implement your own HTTP engine
You can use a different HTTP client with Apollo Kotlin by creating a custom class that implements the HttpEngine interface.
The HttpEngine interface
defines two functions: execute and close. Here's an example implementation that also includes a couple of helper
methods:
1class MyHttpEngine(val wrappedClient: MyClient) : HttpEngine {
2 /**
3 * Helper function to map the Apollo requests to MyClient requests
4 */
5 private fun HttpMethod.toMyClientRequest(): MyClientRequest {
6 ...
7 }
8
9 /**
10 * And the other way around
11 */
12 private fun MyClientResponse.toApolloResponse(): HttpResponse {
13 ...
14 }
15
16 override suspend fun execute(request: HttpRequest) = suspendCancellableCoroutine { continuation ->
17
18 val call = wrappedClient.newCall(request.toMyClientRequest())
19 continuation.invokeOnCancellation {
20 // If the coroutine is cancelled, also cancel the HTTP call
21 call.cancel()
22 }
23
24 wrappedClient.enqueue(
25 call,
26 success = { myResponse ->
27 // Success! report the response
28 continuation.resume(myResponse.toApolloResponse())
29 },
30 error = { throwable ->
31 // Error. Wrap in an ApolloException and report the error
32 continuation.resumeWithException(ApolloNetworkException(throwable))
33 }
34 )
35 }
36
37 override fun close() {
38 // Dispose any resources here
39 }
40}This example uses an asynchronous wrappedClient that runs the network request in a separate thread. Note that because HttpEngine.execute itself is called from a background thread, you can safely block in execute().
Using your HttpEngine
After you create your HttpEngine implementation, you can register it with your ApolloClient instance using ApolloClient.Builder.httpEngine:
1// Use your HttpEngine
2val client = ApolloClient.Builder()
3 .serverUrl(serverUrl = "https://example.com/graphql")
4 .httpEngine(httpEngine = MyHttpEngine(wrappedClient))
5 .build()With this configuration, Apollo Kotlin sends all of its GraphQL operation requests with MyHttpEngine.
Excluding OkHttp on JVM
OkHttp is a ~800kB dependency. If you don't need it otherwise in your app classpath, you can save the dependency by excluding it in your Gradle configuration:
1dependencies {
2 implementation("com.apollographql.apollo:apollo-runtime:$apolloVersion") {
3 exclude(group = "com.squareup.okhttp3")
4 }
5}And customizing the HttpEngine. For an example, you can use the builtin JVM client:
1val httpEngine = object : HttpEngine {
2 override suspend fun execute(request: HttpRequest): HttpResponse {
3 requests.add(Buffer().apply { request.body!!.writeTo(this) }.readUtf8())
4 return HttpResponse.Builder(200)
5 .body(Buffer().writeUtf8(FooQuery.successResponse))
6 .build()
7 }
8
9 override fun close() {}
10}
11
12val apolloClient = ApolloClient.Builder()
13 .serverUrl("https://example.com/graphql")
14 .httpEngine(httpEngine)
15 // If you use WebSocket subscriptions, you must also provide a custom `WebSocketEngine`.
16 .build()This exclusion only applies to Apollo's dependency on OkHttp; other dependencies may still require it. Apollo still requires Okio for its HTTP bodies and JSON readers.
Ktor engine
An implementation of HttpEngine based on Ktor is available in apollographql/apollo-kotlin-ktor-support
Other HTTP customizations
Besides implementing HttpEngine, Apollo Kotlin also supports other methods for customizing HTTP behavior:
No runtime: You can opt out of the Apollo Kotlin runtime completely and only use generated models and parsers. Use this option if you don't need any of the runtime features (caching, batching, automatic persisted queries, etc.).
HTTP interceptors: If you want to add HTTP headers and/or logging to your requests, HTTP interceptors enable you to do this with minimal code.