1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

apollo-kotlin の compose サポートを試してみる (その1)

Last updated at Posted at 2023-08-28

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 し終わったらテスト用にざっくりとクエリを追加しておきます:

Test.gql
query Test {
    allFilms {
        films {
            title
        }
    }
}

テストコード

ざっくりとテストのクエリを投げて、結果を表示するシンプルなものを書いてみます:

Apollo.kt
val apolloClient = ApolloClient.Builder()
    .serverUrl("https://swapi-graphql.netlify.app/.netlify/functions/index")
    .build()
LaunchList.kt
@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 ?: "")
        }
    }
}

これだけでひとまず映画のタイトルリストが出ます:

example

読み込み中の状態も null かどうかで判断できるので、
ローディングインジケーターも出ていますね。

めちゃくちゃなクエリを書いてエラーになったときはエラーハンドリングもできています:

apollo-compose-error.png

query Test {
    allFilms {
        films {
            title
        }
    }

    node(id: "aaaaaaa") { # Error!
        ... on Film {
            title
        }
    }
}

使い心地としては、ライブラリ側で State として扱えるようにしてくれているので、
composable でそのままクエリして渡していけるのは楽ですね。

とはいえ、テストはどうするとか、画面回転に生き残るようにするには、とかよくある話題があるように思えますね。
このあたりを別で調べてみようと思っています。

あとは、ページネーションを考慮できる仕組みもあるようなので、
そのあたりをどういう感じで書いていけるかというところも見てみようと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?