如何使用GraphQL Client: Apollo Android
如何使用GraphQL Client: Apollo Android
一個Android app, 如何使用GraphQL.
本文以最流行的Apollo Android為例來說明.
添加依賴
首先, 添加依賴:
//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="//your.domain/graphql/endpoint" \
--schema="src/main/graphql/com/example/schema.json"
如果是需要認證的endpoint:
./gradlew downloadApolloSchema \
--endpoint="//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測試: //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].
認證請求
關於認證的請求:
//www.apollographql.com/docs/android/tutorial/10-authenticate-your-queries/
同樣也是加interceptor來解決:
return ApolloClient.builder()
.serverUrl("//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)
}
}