如何使用GraphQL Client: Apollo Android
一個Android app, 如何使用GraphQL.
本文以最流行的Apollo Android為例來說明.
添加依賴
首先, 添加依賴:
https://www.apollographql.com/docs/android/essentials/get-started-kotlin/
注意在android block里這兩個東東都要加上:
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
下載Schema
然后, 下載schema.
可以跑一個introspection query來獲取.
Apollo的Gradle插件貼心地提供了這個功能, 用downloadApolloSchema這個task就可以.
只需要提供server的endpoint和存儲schema.json文件的位置:
./gradlew downloadApolloSchema \
--endpoint="https://your.domain/graphql/endpoint" \
--schema="src/main/graphql/com/example/schema.json"
如果是需要認證的endpoint:
./gradlew downloadApolloSchema \
--endpoint="https://your.domain/graphql/endpoint" \
--schema="app/src/main/graphql/com/example" \
--header="Authorization: Bearer $TOKEN"
這里我曾經有過一個疑問, 我這個TOKEN屬於哪個用戶的要緊嗎? -> 不要緊.
注意: 此時用的Token只是為了獲取schema, 實際請求的時候還是要帶具體當時的token.
添加.graphql文件, build生成代碼
找Playground測試, 比如GitHub GraphQL API可以用Explorer測試: https://developer.github.com/v4/explorer/
然后把這個.graphql文件寫在schema文件旁邊.
比如:
CurrentUser.graphql中:
query CurrentUser {
viewer {
login
avatarUrl
name
}
}
Build, 生成代碼.
生成代碼在生成文件的路徑.
比如CurrentUser.graphql里面是一個query, 就生成了CurrentUserQuery文件.
進行請求調用 (協程版本)
采用協程版本的代碼, 在ViewModel的scope里面:
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}")
}
其中toDeferred()方法將結果轉換為Deferred<T>, 是Job的一個子類, await()方法返回協程的結果.
Apollo Client Android的協程支持
添加了這個依賴之后:
implementation("com.apollographql.apollo:apollo-coroutines-support:2.2.3")
會有一個輔助類, 里面目前是5個擴展方法:
- 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].
認證請求
關於認證的請求:
https://www.apollographql.com/docs/android/tutorial/10-authenticate-your-queries/
同樣也是加interceptor來解決:
return ApolloClient.builder()
.serverUrl("https://api.github.com/graphql")
.okHttpClient(
OkHttpClient.Builder()
.addInterceptor(authInterceptor)
.build()
)
.build()
其中authInterceptor和用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)
}
}
