Fragments in Apollo Kotlin
ⓘ NOTE
This article describes the behavior of fragments when using the default operationBased
codegen in Apollo Kotlin. For the responseBased
codegen, 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:
# Declaration of named fragmentfragment LaunchFragment on Launch {idsitemission {name}}query LaunchDetails($id:ID!) {launch(id: $id) {# Usage of named fragment...LaunchFragment}}
Based on the fragment
definition, Apollo Kotlin generates the following LaunchFragment
class that you can reuse in different queries:
data class LaunchFragment(val id: String,val site: String?,val mission: Mission?)
Generated models for operations that use this fragment have a .launchFragment
property for accessing the fragment's fields:
println("Mission site: ${launch.launchFragment?.site}")
The launchFragment
property is null
if the returned object is not a Launch
.
You can reuse the fragment in any number of operations:
# ...previous definitions...query LaunchList {launches {launches {...LaunchFragment}}}
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:
query HeroForEpisode($ep: Episode!) {hero(episode: $ep) {name... on Droid {primaryFunction}... on Human {height}}}
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
:
println("Droid primaryFunction: ${hero.onDroid?.primaryFunction}")println("Human height: ${hero.onHuman?.height}")
These on<ShapeName>
fields (onDroid
and onHuman
) are null
if the returned object is not of the corresponding type.