apollo-kotlin 3.8.0 から experimental ですが、
Jetpack Compose で Apollo のクエリが使いやすくなる拡張サポートが入りました。
どんな使い心地か試してみようと思います。
セットアップ
適当なサンプルの GraphQL API を探してきます。ちょうど Apollo のブログ記事にデモに使える GraphQL API の紹介があるのでみてみます:
ポケモンずかんとかアニメのリストの公開 API があって面白いですね。よく使われているスターウォーズの API を使ってみます:
スキーマを DL しておきます:
./gradlew :app:downloadApolloSchema --endpoint='https://swapi-graphql.netlify.app/.netlify/functions/index' --schema=app/src/main/graphql/schema.graphqls
DL し終わったらテスト用にざっくりとクエリを追加しておきます:
query Test {
allFilms {
films {
title
}
}
}
テストコード
ざっくりとテストのクエリを投げて、結果を表示するシンプルなものを書いてみます:
val apolloClient = ApolloClient.Builder()
.serverUrl("https://swapi-graphql.netlify.app/.netlify/functions/index")
.build()
@OptIn(ApolloExperimental::class)
@Composable
private fun FilmList(apolloClient: ApolloClient) {
val response by apolloClient.query(TestQuery()).toState()
val data = response?.data
val exception = response?.exception
when {
response == null -> CircularProgressIndicator()
exception != null || response?.hasErrors() == true -> {
Text(text = "Error!")
}
data != null -> {
FilmList(films = data.allFilms?.films ?: emptyList())
}
}
}
@Composable
private fun FilmList(
films: List<TestQuery.Film?>,
modifier: Modifier = Modifier,
) {
LazyColumn(modifier = modifier) {
items(items = films) { film ->
Text(text = film?.title ?: "")
}
}
}
これだけでひとまず映画のタイトルリストが出ます:
読み込み中の状態も null
かどうかで判断できるので、
ローディングインジケーターも出ていますね。
めちゃくちゃなクエリを書いてエラーになったときはエラーハンドリングもできています:
query Test {
allFilms {
films {
title
}
}
node(id: "aaaaaaa") { # Error!
... on Film {
title
}
}
}
使い心地としては、ライブラリ側で State として扱えるようにしてくれているので、
composable でそのままクエリして渡していけるのは楽ですね。
とはいえ、テストはどうするとか、画面回転に生き残るようにするには、とかよくある話題があるように思えますね。
このあたりを別で調べてみようと思っています。
あとは、ページネーションを考慮できる仕組みもあるようなので、
そのあたりをどういう感じで書いていけるかというところも見てみようと思います。