How to use graphql client: Apollo Android

Time:2021-5-2

How to use graphql client: Apollo Android

An android app, how to use graphql
This article takes the most popular Apollo android as an example

Add dependency

First, add the dependency:
https://www.apollographql.com/docs/android/essentials/get-started-kotlin/

Note that in Android block, the following two things should be added:

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

Download schema

Then, download the schema
You can run an introspection query to get it

Apollo’s gradle plug-in provides this function with caredownloadApolloSchemaThis task is OK

You only need to provide the endpoint of the server and the location to store the schema.json file

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

If the endpoint needs authentication:

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

Here I once had a question: does it matter which user my token belongs to never mind.
Note: the token used at this time is only for obtaining the schema, and the specific token at that time should be brought when the actual request is made

Add. Graphql file and build code

Find the playground test. For example, GitHub graphql API can be tested with Explorerhttps://developer.github.com/v4/explorer/

And then put this.graphqlThe file is written next to the schema file
For example:
CurrentUser.graphqlMedium:

query CurrentUser {
  viewer {
    login
    avatarUrl
    name
  }
}

Build, generate code

The path of the generated code in the generated file
such asCurrentUser.graphqlThere is a query, and it is generatedCurrentUserQueryFile

Make request call (coroutine version)

Use the code of the coroutine version. In the scope of ViewModel:

viewModelScope.launch {
    val response = try {
        apolloClient.query(CurrentUserQuery()).toDeferred().await()
    } catch (e: ApolloException) {
        // handle protocol errors
        [email protected]
    }

    val viewer = response.data?.viewer
    if (viewer == null || response.hasErrors()) {
        // handle application errors
        [email protected]
    }
    _user.postValue(viewer)

    println("Launch site: ${viewer.login}")
}

amongtoDeferred()Method to convert the result toDeferredYesJobA subclass of,await()Method returns the result of the coroutine

Coroutine support for Apollo client Android

After adding this dependency:

implementation("com.apollographql.apollo:apollo-coroutines-support:2.2.3")

There will be an auxiliary class, in which there are currently 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 authentication:
https://www.apollographql.com/docs/android/tutorial/10-authenticate-your-queries/

The problem is also solved by adding interceptor

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

Among them, authinterceptor is the same as when using 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)
    }
}

reference resources

Recommended Today

Looking for frustration 1.0

I believe you have a basic understanding of trust in yesterday’s article. Today we will give a complete introduction to trust. Why choose rust It’s a language that gives everyone the ability to build reliable and efficient software. You can’t write unsafe code here (unsafe block is not in the scope of discussion). Most of […]