如何使用GraphQL Client: Apollo Android
阿新 • • 發佈:2021-02-24
# 如何使用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`, 是`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)
}
}
```
## 參考
* [Apollo Android官網文件](https://www.apollographql.com/docs/an