Fragments in Apollo Kotlin
Note: This article describes the behavior of fragments when using the default
operationBasedcodegen in Apollo Kotlin. For theresponseBasedcodegen, see this page.
Apollo Kotlin supports both forms of GraphQL fragments:
Named fragments, which enable you to reuse a set of fields across multiple operations
Inline fragments, which enable you to access fields of polymorphic types
Named fragments
Take a look at the following GraphQL definitions:
1# Declaration of named fragment
2fragment launchFragment on Launch {
3 id
4 site
5 mission {
6 name
7 }
8}
9
10query LaunchDetails($id:ID!) {
11 launch(id: $id) {
12 # Usage of named fragment
13 ...launchFragment
14 }
15}Based on the fragment definition, Apollo Kotlin generates the following LaunchFragment class that you can reuse in different queries:
1data class LaunchFragment(
2 val id: String,
3 val site: String?,
4 val mission: Mission?
5)Generated models for operations that use this fragment have a .launchFragment property for accessing the fragment's fields:
1println("Mission site: ${launch.launchFragment?.site}")The
launchFragmentproperty isnullif the returned object is not aLaunch.
You can reuse the fragment in any number of operations:
1 # ...previous definitions...
2
3query LaunchList {
4 launches {
5 launches {
6 ...launchFragment
7 }
8 }
9}You can even use a fragment in operations that are defined in a different .graphql file from the fragment itself. This is because Apollo Kotlin codegen merges all .graphql files in to a single file before generating models.
Inline fragments
Take a look at this query definition that uses two inline fragments:
1query HeroForEpisode($ep: Episode!) {
2 hero(episode: $ep) {
3 name
4 ... on Droid {
5 primaryFunction
6 }
7 ... on Human {
8 height
9 }
10 }
11}For this operation, Apollo Kotlin generates a Hero class that contains OnDroid and OnHuman nested classes. Hero also includes onDroid and onHuman fields that enable you to access fields that are specific to Droid and Human:
1println("Droid primaryFunction: ${hero.onDroid?.primaryFunction}")
2println("Human height: ${hero.onHuman?.height}")These
on<ShapeName>fields (onDroidandonHuman) arenullif the returned object is not the corresponding type.