Interceptors
HTTP interceptors
Apollo HTTP interceptors
Apollo Kotlin supports multi-platform HttpInterceptor
very similar to OkHttp
Interceptors
. Use them to add authentication headers, log the network calls or anything else.
The interface is a single method. For an example, implementing an authentication interceptors can be done with:
1class AuthorizationInterceptor(val token: String) : HttpInterceptor {
2 override suspend fun intercept(request: HttpRequest, chain: HttpInterceptorChain): HttpResponse {
3 return chain.proceed(request.newBuilder().addHeader("Authorization", "Bearer $token").build())
4 }
5}
Then add the interceptor to your HttpNetworkTransport
:
1val apolloClient = ApolloClient.Builder()
2 .serverUrl("https://example.com/graphql")
3 .addHttpInterceptor(AuthorizationInterceptor(token))
4 .build()
Apollo Kotlin comes bundled with ClientAwarenessInterceptor
and LoggingInterceptor
that you can set on your ApolloClient.
OkHttp interceptors
If your project is an Android or JVM only project, and you already have an OkHttp
Interceptor
, you can also reuse it:
1val okHttpClient = OkHttpClient.Builder()
2 .addInterceptor(interceptor)
3 .build()
4
5val apolloClient = ApolloClient.Builder()
6 .serverUrl("https://example.com/graphql")
7 .okHttpClient(okHttpClient)
8 .build()
GraphQL interceptors
Apollo also supports interceptors at the GraphQL level: ApolloInterceptor
. They are useful to customize operations before they are sent, or to react to the response, in a centralized way. For example, you could use them to keep track of certain errors, or to implement authentication if the server handles it at the GraphQL level rather than HTTP. Under the hood, Apollo implements the normalized cache, and APQ features with ApolloInterceptor
.
Like HttpInterceptor
, ApolloInterceptor
also has a single method, but the API is Flow
based. Remember that the Flow
can emit several times, for instance in the case of Subscriptions.
Here's an example of a logging interceptor:
1class LoggingApolloInterceptor: ApolloInterceptor {
2 override fun <D : Operation.Data> intercept(request: ApolloRequest<D>, chain: ApolloInterceptorChain): Flow<ApolloResponse<D>> {
3 return chain.proceed(request).onEach { response ->
4 println("Received response for ${request.operation.name()}: ${response.data}")
5 }
6 }
7}
Then add the interceptor to your ApolloClient
:
1val apolloClient = ApolloClient.Builder()
2 .serverUrl("https://example.com/graphql")
3 .addInterceptor(LoggingApolloInterceptor())
4 .build()