Gradle plugin recipes
Using multiple GraphQL APIs
Apollo Kotlin supports communicating with multiple GraphQL endpoints with different schemas. To do so, create multiple services like so:
1apollo {
2 service("starwars") {
3 srcDir("src/main/graphql/starwars")
4 packageName.set("com.starwars")
5 }
6 service("githunt") {
7 srcDir("src/main/graphql/githunt")
8 packageName.set("com.githunt")
9 }
10}
Specifying the schema location
Specify the location of your schema file using the schemaFiles
property:
1apollo {
2 service("service") {
3 schemaFiles.from(file("shared/graphql/schema.graphqls"))
4 }
5}
IfschemaFiles
is not set, Apollo Kotlin combines all*.[graphqls|json|sdl]
files insrc/main/graphql/
(Android/JVM projects) orsrc/commonMain/graphql/
(multiplatform projects).
Combining multiple schema files
Apollo Kotlin supports a collection of directives, such as @semanticNonNull
, @fieldPolicy
, @typePolicy
. These
directives enable you to extend your server's base schema to work better with your client.
If you expand your schema in a separate file (usually named extra.graphqls
), you can instruct Apollo Kotlin to construct its schema from a combination
of multiple files, like so:
1apollo {
2 service("service") {
3 schemaFiles.from("shared/graphql/schema.graphqls", "shared/graphql/extra.graphqls")
4 }
5}
Wiring generated sources
By default, Apollo Kotlin adds the generated sources:
to the
main
sourceSet for JVM projectsto
commonMain
for multiplatform projectsto all non-test variants for Android projects
You can customize this behavior with the outputDirConnection
property. For example, to wire a service to the test source set of a Kotlin JVM project:
1apollo {
2 service("service") {
3 outputDirConnection {
4 connectToKotlinSourceSet("test")
5 }
6 }
7}
Android variants support
It is sometimes useful to have different operations or schemas depending on the variant of your Android project.
To do this, you can instruct the Gradle plugin to automatically configure a Service per variant:
1apollo {
2 createAllAndroidVariantServices(sourceFolder = ".", nameSuffix = "") {
3 // Configure the service here
4 packageName.set("...")
5 }
6}
sourceFolder
is where to find the GraphQL relative to "src/$sourceSetName/graphql". Pass "." to look into "src/$sourceSetName/graphql".nameSuffix
is the suffix to use for the service name. Leave blank to use the variant name as is.
Similarly to what the Android variant system does with source code, the GraphQL files are handled additively, and files in src/main/graphql
are included in all services.
For instance, if certain operations should only exist in debug builds, your project structure could look like this:
1- main
2 - graphql
3 - schema.graphqls // Schema for all variants
4 - operations.graphql // Operations shared by all variants
5- debug
6 - graphql
7 - operations.graphql // Operations specific to the 'debug' build type
Or if you have a specific backend per flavor, it could look like this:
1- main
2- demo
3 - graphql
4 - schema.graphqls // Schema for the 'demo' flavor
5 - operations.graphql // Operations specific to the 'demo' flavor
6- full
7 - graphql
8 - schema.graphqls // Schema for the 'full' flavor
9 - operations.graphql // Operations specific to the 'full' flavor
If you have a lot of variants and don't need to configure an Apollo Service for each, it may be simpler to declare the Services manually rather than using createAllAndroidVariantServices
. For instance:
1apollo {
2 service("debug") {
3 srcDir(file("src/debug/graphql/"))
4 packageName.set("com.example")
5 outputDirConnection {
6 connectToAndroidSourceSet("debug")
7 }
8 }
9 service("release") {
10 srcDir(file("src/release/graphql/"))
11 packageName.set("com.example")
12 outputDirConnection {
13 connectToAndroidSourceSet("release")
14 }
15 }
16}
Downloading a schema
The Apollo Gradle plugin has APIs to download a schema from introspection:
1apollo {
2 service("starwars") {
3 packageName.set("com.starwars")
4
5 // This creates a downloadStarwarsApolloSchemaFromIntrospection task
6 introspection {
7 endpointUrl.set("https://your.domain/graphql/endpoint")
8 // The path is interpreted relative to the current project
9 schemaFile.set(file("src/main/graphql/com/example/schema.graphqls"))
10 }
11 }
12}
This creates a task named download${ServiceName}ApolloSchemaFromIntrospection
.
If introspection is disabled and your team is using GraphOS, use the registry {}
block
instead:
1apollo {
2 service("starwars") {
3 packageName.set("com.starwars")
4
5 // This creates a downloadStarwarsApolloSchemaFromRegistry task
6 registry {
7 key.set(System.getenv("APOLLO_KEY"))
8 graph.set(System.geten("APOLLO_GRAPH"))
9 // The path is interpreted relative to the current project here, no need to prepend 'app'
10 schemaFile.set(file("src/main/graphql/com/example/schema.graphqls"))
11 }
12 }
13}
This creates a task named download${ServiceName}ApolloSchemaFromRegistry
.
With the Android Studio plugin, you can also go to Tools | Apollo | Download schema which acts as a shortcut to these tasks.
Alternatively, for one time downloads, you can also use the Apollo Kotlin cli.
Generated methods
By default, all Kotlin models, operations, fragments, and input objects are generated as data classes. This means that the Kotlin compiler will
auto-generate toString
, equals
hashCode
, copy
and componentN
for most generated classes. If you don't think you need all of those
auto-generated methods, and/or you are worried about the size of the generated code, you can configure the Apollo compiler to generate none
or a subset of the data class methods. To do this, set generateMethods
to a list of the methods you need. The available methods are:
"equalsHashCode" generates
equals
andhashCode
methods that will compare generated class properties."toString" generates a method that will print a pretty string representing the data in the class.
"copy" (Kotlin only) generates a method that will copy the class with named parameters and default values.
"dataClass" (Kotlin only and redundant with all other methods) generates the class as a data class. which will automatically generate
toString
,copy
,equals
andhashCode
.
Here are some possible configurations:
1apollo {
2 service("service") {
3 // Generates equals and hashCode
4 generateMethods.set(listOf("equalsHashCode"))
5 // Generates toString, equals, and hashcode (the default for Java)
6 generateMethods.set(listOf("equalsHashCode", "toString"))
7 // Only generates copy
8 generateMethods.set(listOf("copy"))
9 // Generates data classes (the default for Kotlin)
10 generateMethods.set(listOf("dataClass"))
11 }
12}