Multi Modules codegen
For multi-modules projects, Apollo Kotlin enables you to define queries in a feature module and reuse fragments and types from another module dependency. This helps with better separation of concerns and build times.
ⓘ NOTE
This page is for sharing a schema between different modules and defining your .graphql
operations in different modules. If all your .graphql
files are in a single module, you can use apollo-runtime
like any other Kotlin dependency without any of this.
Setup
Multi-modules requires that one and only one module contains a schema. This is the schema that all other modules can reuse. In this document, we'll refer to this module as the "schema module".
In your schema module, opt-in multi-module by generating metadata for use by downstream feature modules:
// schema/build.gradle.ktsapollo {service("service") {packageName.set("schema")// Enable generation of metadata for use by downstream modulesgenerateApolloMetadata.set(true)// If you need to specify the location of your schema filesschemaFiles.from(/*...*/)// Scalar mappings and generateDataBuilders must be defined in the schema modulemapScalar(/*...*/)generateDataBuilders.set(true)// Other options can be different between modules.// If you want those options to be applied to all modules, use a convention plugin and shared build logic.useSemanticNaming.set(true)generateFragmentImplementations.set(true)}}
In your feature module, declare your schema module as a dependency:
// feature/build.gradle.ktsapollo {// Service names must matchservice("service") {packageName.set("feature")// The 'feature' depends on the 'schema' moduledependsOn(project(":schema"))}}
Auto-detection of used types
By default, Apollo Kotlin generates all the types in your schema module. This is because there is no way to know in advance what types are going to be used by feature modules.
For large schemas, this can generate a lot of code and increase your build time significantly. In this case, you can opt in auto-detection of used types. This works by splitting the codegen task in different steps so that feature modules can let the schema module know what types are used before actually generating the models. To opt in, call dependsOn()
with the bidirectional
argument set to true:
// feature/build.gradle.ktsapollo {service("service") {packageName.set("feature")// Use `bidirectional` to have the schema module get the used types from this moduledependsOn(dependencyNotation = project(":schema"), bidirectional = true)}}
The bidirectional
parameter is experimental because it may break Gradle project isolation. For a project-isolation compatible method, try isADependencyOf
Once you opt in auto-detection of used types, it's important that all modules are doubly linked like above. If not the feature modules will fail to compile due to some missing schema classes.