Upgrade to Pro — share decks privately, control downloads, hide ads and more …

State management and API calls in Jetpack Compose: Learning Apollo + Jetpack Compose through React Hooks

State management and API calls in Jetpack Compose: Learning Apollo + Jetpack Compose through React Hooks

Jetpack Composeの状態管理とAPIコール - React Hooksに習う、Apollo + Jetpack Compose
DroidKaigi 2022にて発表
https://github.com/yt8492/ApolloComposeTodoApp

Yuta Tomiyama

October 05, 2022
Tweet

More Decks by Yuta Tomiyama

Other Decks in Programming

Transcript

  1. State management and API calls
    in Jetpack Compose:
    Learning Apollo + Jetpack Compose
    through React Hooks
    DroidKaigi 2022

    View Slide

  2. About me
    ● Yuta Tomiyama (富山 雄太)
    ● Working at: DMM.com LLC
    ● Second job: Appify Technologies, Inc.
    ● Android Engineer
    ● Twitter: マヤミト(mayamito)@yt8492
    ● GitHub: yt8492

    View Slide

  3. Do you use Jetpack Compose and
    GraphQL(Apollo) ?

    View Slide

  4. How do you manage state and API calls?

    View Slide

  5. Today we learn Apollo + Jetpack Compose
    and state management
    through Apollo + React

    View Slide

  6. Learn what Apollo + React provided and solved
    This Session's Goal

    View Slide

  7. Learn what Apollo + React provided and solved
    Then think of state management and API calls in Apollo + Jetpack Compose
    through Apollo + React and how to realize it
    This Session's Goal

    View Slide

  8. Introduction
    ● What's React?
    ● What's GraphQL?
    ● What's Apollo Client(JavaScript)?
    ● What Apollo + React enable?

    View Slide

  9. What's React?
    ● React is a JavaScript library for building user interfaces
    ● Declarative UI
    ● UI Component written in pure JavaScript

    View Slide

  10. React and Jetpack Compose has similar feature
    ● Declarative UI
    ● Functional Component → Composable Function
    ● Hooks → Composable Function
    ○ useState → remenber mutableStateOf
    ○ useEffect → LaunchedEffect, DisposableEffect
    ○ Custom Hooks → Custom Comosable Function

    View Slide

  11. React and Jetpack Compose has similar feature
    ● Functional Component and Composable Function

    View Slide

  12. React and Jetpack Compose has similar feature
    ● Hooks → Composable Function

    View Slide

  13. What's GraphQL?
    ● GraphQL is a query language for APIs
    ○ Type safe
    ○ Send a single GraphQL query to API and get all the data your app needs
    ■ No overfetch
    ■ No underfetch
    ● GraphQL is modeling the business domain in a graph structure
    ○ Fetching resources: query
    ○ Updating resources: mutation

    View Slide

  14. What's Apollo Client(JavaScript)?
    ● Comprehensive state management library, not only to call GraphQL API
    ● Manage both local and remote data with GraphQL
    ○ Declarative data fetching
    ○ Intelligent caching
    ● Designed for modern React
    ○ Apollo Client library provides hooks API(useQuery, useMutation)

    View Slide

  15. Declarative Data Fetching
    Apollo Client's hooks encapsulates the logic for retrieving your data, tracking
    loading and error states, and updating your UI.

    View Slide

  16. useQuery
    When start fetching
    ○ data = undefined
    ○ loading = true
    ○ error = undefined

    View Slide

  17. useQuery
    When finish fetching and returned correct response
    ○ data = query result
    ○ loading = false
    ○ error = undefined

    View Slide

  18. useQuery
    When finish fetching and returned error
    ○ data = undefined
    ○ loading = false
    ○ error = GraphQL error

    View Slide

  19. useMutation
    Initial state
    ○ data = undefined
    ○ loading = false
    ○ error = undefined

    View Slide

  20. useMutation
    When click CreateTodoButton and start mutation
    ○ data = undefined
    ○ loading = true
    ○ error = undefined

    View Slide

  21. useMutation
    When finish mutation successfully and returned response
    ○ data = mutation result
    ○ loading = false
    ○ error = undefined

    View Slide

  22. useMutation
    When finish mutation and returned error
    ○ data = undefined
    ○ loading = false
    ○ error = GraphQL error

    View Slide

  23. Intelligent Caching
    When client has no Book cache:

    View Slide

  24. Intelligent Caching
    When client has Book cache:

    View Slide

  25. Intelligent Caching
    useQuery results are automatically updated by cache hit

    View Slide

  26. Intelligent Caching
    useQuery results are automatically updated by cache hit

    View Slide

  27. Intelligent Caching
    ● Apollo Client can store cache GraphQL query result in a graph structure
    ○ Entities in the graph are identified by id and __typename and automatically normalized
    ○ Programmers no need to manage the cache themselves
    ● Apollo Client updates query result automatically when local cache
    updated by data from server
    ● You can use the query result of Apollo Client as a Single Source of Truth

    View Slide

  28. Introduction Overview
    ● React and Jetpack Compose has similar feature
    ● GraphQL is a type safe query language for APIs
    ● Apollo Client is a comprehensive state management library for React
    ● Apollo + React enable Single Source of Truth architecture

    View Slide

  29. Introduction Overview
    ● React and Jetpack Compose has similar feature
    ● GraphQL is a type safe query language for APIs
    ● Apollo Client is a comprehensive state management library for React
    ● Apollo + React enable Single Source of Truth architecture
    → We can do the same things with Apollo + Jetpack Compose

    View Slide

  30. Introduce Apollo Kotlin
    ● Apollo Client for Kotlin
    ● Generate Kotlin codes from GraphQL queries
    ● Features
    ○ Kotlin code generation
    ○ Kotlin Coroutines support
    ○ Normalized cache
    ■ InMemory
    ■ SQLite
    ○ etc…

    View Slide

  31. Execute Query using Apollo Kotlin
    ● Composable functions are not yet provided 😭
    ○ We can't execute query like useQuery

    View Slide

  32. Create Composable Function like Apollo Client Hooks
    ● We can create hooks-like composable function by wrapping Apollo Kotlin
    Client
    ● Implement extension functions to Apollo Kotlin Client with reference to
    the JavaScript Apollo Client API
    React Hooks Composable Function
    useQuery
    useMutation
    watch
    mutation
    query
    mutation

    View Slide

  33. Apollo Wrapper and Todo APP Example Repository
    yt8492 / ApolloComposeTodoApp
    https://github.com/yt8492/ApolloComposeTodoApp

    View Slide

  34. Implement watch() Composable Function
    React hooks Composable Function
    useQuery
    useMutation
    watch
    mutation
    query
    mutation

    View Slide

  35. See the useQuery API
    ● Arguments
    ○ Parsed GraphQL query string
    ○ variables
    ● Results
    ○ data(GraphQL query result)
    ○ loading(If true, the query is still in flight and results have not yet been returned)
    ○ error(Either an array of graphQLErrors or a single networkError)
    ○ refetch(Re-execute query function)

    View Slide

  36. Implement in Jetpack Compose
    ● Think of composable function interface

    View Slide

  37. Implement watchAsFlow()
    ● Share watch logic with first fetch and refetch
    ○ First implement function returns flow and convert result in it

    View Slide

  38. Implement watchAsFlow()

    View Slide

  39. Implement watchAsFlow()

    View Slide

  40. Define Error Type

    View Slide

  41. Define Error Type

    View Slide

  42. Implement watch() Composable Function

    View Slide

  43. Implement watch() Composable Function

    View Slide

  44. Implement mutation() Composable Function
    React hooks Composable Function
    useQuery
    useMutation
    watch
    mutation
    query
    mutation

    View Slide

  45. See the useMutation API
    ● Arguments
    ○ mutation(Parsed GraphQL query string)
    ● Results
    ○ mutateFunction(A function to trigger the mutation)
    ○ data(Returned from mutation)
    ○ loading(If true, the mutation is currently in flight)
    ○ error(Either an array of graphQLErrors or a single networkError)

    View Slide

  46. Implement in Jetpack Compose
    ● Think of composable function interface

    View Slide

  47. Implement in Jetpack Compose
    ● Think of composable function interface

    View Slide

  48. Implement mutation() Composable Function

    View Slide

  49. Example: TodoAPP
    ● Pages
    ○ Todo List Page
    ○ Todo Detail Page
    ○ Todo Create Page

    View Slide

  50. Server Schema

    View Slide

  51. Cache Setting

    View Slide

  52. Todo List Page
    ● Show all todos
    ● Show completed todos
    ● Show UnCompleted todos
    ● Toggle todo done status
    ● Navigate to todo create page
    ● Navigate to todo detail page

    View Slide

  53. Todo List Page Query and Mutation

    View Slide

  54. Execute Todo List Page Query and Mutation

    View Slide

  55. Update UI Immediately When Execute Mutation
    mutation returns todos and cache saved
    click checkbox
    watched query results updated by cache
    UI updated

    View Slide

  56. Todo Detail Page
    ● Show selected todo
    ● Toggle todo done status

    View Slide

  57. Todo Detail Page Query and Mutation

    View Slide

  58. Execute Todo Detail Page Query and Mutation

    View Slide

  59. Execute Todo Detail Page Query and Mutation

    View Slide

  60. Todo List Updated When Toggle in Todo Detail

    View Slide

  61. Todo Create Page
    ● Input todo title
    ● Create todo button

    View Slide

  62. Todo Create Page Mutation

    View Slide

  63. Execute Todo Create Page Mutation

    View Slide

  64. Todo List Updated When Todo Created
    navigate to
    create page
    pop back to
    list page
    updated list
    by cache

    View Slide

  65. 🎉

    View Slide

  66. When the cache is not updated

    View Slide

  67. When the cache is not updated

    View Slide

  68. When the cache is not updated
    mutation executed but updated todo not returned
    click checkbox
    watched query results are not updated
    nothing changed

    View Slide

  69. Apollo Wrapper and Todo APP Example Repository
    yt8492 / ApolloComposeTodoApp
    https://github.com/yt8492/ApolloComposeTodoApp

    View Slide

  70. Conclusion
    ● Apollo Client is a comprehensive state management library, not only to
    call GraphQL API
    ○ Apollo Client enables Single Source of Truth architecture
    ○ Apollo Client + React enables declarative data fetching
    ○ Apollo + React make easy to state management and API calls in frontend development
    ○ But Apollo Kotlin not yet provide composable functions like Apollo Client hooks API
    ● We can create composable function like Apollo Client hooks API by
    wrapping Apollo Kotlin
    ○ We can enable Single Source of Truth architecture and declarative data fetching in Jetpack
    Compose
    ○ Apollo + Jetpack Compose make easy to state management and API calls in Android
    development

    View Slide

  71. Appendix: Think of other API call
    ● You can also fetch data declarative in other API
    ○ Create Composable function to call API
    ○ returns data, loading, error states and update

    View Slide

  72. View Slide

  73. Thank you!

    View Slide

  74. Bibliography
    1. https://reactjs.org/
    2. https://reactjs.org/docs/components-and-props.html
    3. https://reactjs.org/docs/hooks-intro.html
    4. https://graphql.org/
    5. https://graphql.org/learn/
    6. https://www.apollographql.com/docs/
    7. https://www.apollographql.com/docs/react
    8. https://www.apollographql.com/docs/react/why-apollo
    9. https://www.apollographql.com/docs/react/caching/overview

    View Slide

  75. Bibliography
    10. https://www.apollographql.com/docs/react/data/queries
    11. https://www.apollographql.com/docs/react/data/mutations
    12. https://www.apollographql.com/docs/kotlin
    13. https://www.apollographql.com/docs/kotlin/essentials/queries
    14. https://www.apollographql.com/docs/kotlin/caching/query-watchers
    15. https://www.apollographql.com/docs/kotlin/essentials/mutations
    16. https://www.apollographql.com/docs/kotlin/caching/programmatic-ids

    View Slide