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:

Kotlin
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:

Kotlin
1apollo {
2  service("service") {
3    schemaFiles.from(file("shared/graphql/schema.graphqls"))
4  }
5}
note
If schemaFiles is not set, Apollo Kotlin combines all *.[graphqls|json|sdl] files in src/main/graphql/ (Android/JVM projects) or src/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:

Kotlin
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 projects

  • to commonMain for multiplatform projects

  • to 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:

Kotlin
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:

Kotlin
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:

Text
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:

Text
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:

Kotlin
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:

Kotlin
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:

Kotlin
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 and hashCode 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 and hashCode.

Here are some possible configurations:

Kotlin
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}
Feedback

Edit on GitHub

Forums