How to use GraphQL Client: Apollo Android

How to use GraphQL for Android app. This article uses the most popular Apollo Android as an example.

Add the dependent

First, add depends on: www.apollographql.com/docs/androi…

Note that both of these items are added to the Android Block:

compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions {jvmTarget = '1.8'}Copy the code

Download the Schema

Then, you download the schema. You can run an Introspection query to get it.

Apollo’s Gradle plugin nicely provides this functionality, using the task downloadApolloSchema.

You only need to provide the endpoint of the server and the location where the schema.json file is stored:

./gradlew downloadApolloSchema \
  --endpoint="https://your.domain/graphql/endpoint" \
  --schema="src/main/graphql/com/example/schema.json"
Copy the code

For an endpoint that requires authentication:

./gradlew downloadApolloSchema \
  --endpoint="https://your.domain/graphql/endpoint" \
  --schema="app/src/main/graphql/com/example" \
  --header="Authorization: Bearer $TOKEN"
Copy the code

Here I once had a question: does it matter which user my TOKEN belongs to? Note: the Token is only used to obtain the schema, and the actual request still needs to carry the specific Token at that time.

Add.graphQL file, build to generate code

Find Playground test, such as making GraphQL API can use Explorer test: developer.github.com/v4/explorer…

And then I’m going to put this.graphQL file next to the schema file. Currentuser.graphql:

query CurrentUser {
  viewer {
    login
    avatarUrl
    name
  }
}
Copy the code

Build, generate code.

Build code in the build file path. For example, if currentUser. graphQL contains a query, CurrentUserQuery is generated.

Making the request invocation (coroutine version)

Using the coroutine version of the code in the scope of the ViewModel:

viewModelScope.launch { val response = try { apolloClient.query(CurrentUserQuery()).toDeferred().await() } catch (e: ApolloException) { // handle protocol errors return@launch } val viewer = response.data? .viewer if (viewer == null || response.hasErrors()) { // handle application errors return@launch } _user.postValue(viewer) println("Launch site: ${viewer.login}") }Copy the code

The toDeferred() method converts the result toDeferred

, which is a subclass of Job, and the await() method returns the result of the coroutine.

Apollo Client Android coroutine support

After adding this dependency:

Implementation (" com. Apollographql. Apollo, Apollo - coroutines - support: 2.2.3 ")Copy the code

There will be a helper class that currently has five extension methods:

  • Converts an [ApolloCall] to an [Flow]
  • Converts an [ApolloQueryWatcher] to an [Flow].
  • Converts an [ApolloCall] to an [Deferred].
  • Converts an [ApolloSubscriptionCall] to an [Flow].
  • Converts an [ApolloPrefetch] to [Job].

Authentication request

Request for certification: www.apollographql.com/docs/androi…

Also add interceptor to solve this problem:

return ApolloClient.builder()
    .serverUrl("https://api.github.com/graphql")
    .okHttpClient(
        OkHttpClient.Builder()
            .addInterceptor(authInterceptor)
            .build()
    )
    .build()
Copy the code

AuthInterceptor is the same as Retrofit.

class AuthInterceptor constructor(private val preferencesUtils: PreferencesUtils) : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val userToken = preferencesUtils.userToken val newBuilder = chain.request().newBuilder() if (userToken ! = null && userToken.isNotEmpty()) { newBuilder.addHeader("Authorization", "token $userToken") } newBuilder.addHeader("Accept", "application/vnd.github.v3+json") val request = newBuilder.build() return chain.proceed(request) } }Copy the code

reference

  • Apollo Android official documentation