Migration guides
Migrate from older versions of Apollo Android
Migrating to 2.x
Kotlin Multiplatform
We are really excited to announce that with this release it is possible to build Kotlin Multiplatform apps with Apollo. The supported targets are Android / iOS / JVM.
Please check-out samples/multiplatform
for sample application.
This is a backward compatible change for existing users. Please keep in mind that it will bring Kotlin standard library as a transitive dependency.
Side effect changes of Kotlin migration:
- Some primitive types like
Boolean
s may be unboxed where appropriate - Classes and functions are
final
unless they are intentionally marked asopen
- Kotlin-stdlib is added as a transitive dependency
- Jvm target version is now 1.8. See the Android Developer website for details on how to enable it in yout project.
Okio migration
Okio has been updated to 2.4.3 for Kotlin multiplatform.
The new version of okio is binary compatible. There are some source incompatible changes for Kotlin users like Java static function being moved to Kotlin extension functions.
If you explicitly depend okio, it is recommended to do a major version upgrade before upgrading Apollo.
Note: while we initially considered upgrading Okhttp to version 4.x, we ultimately reverted the change to keep compatibility with Android 4.4. More details in #2054 and 2269.
New Normalized Cache Modules
For in-memory LruNormalizedCache
users, no change required since apollo-runtime
brings it as transitive dependency. It is still
recommended adding the following dependency explicitly: implementation("com.apollographql.apollo:apollo-normalized-cache:x.y.z")
Apollo normalized cache module (#2142)
SqlNormalizedCache
is moved to its own module. If you added apollo-android-support
for disk cache, replace it with new dependency.
// Replace:
implementation("com.apollographql.apollo:apollo-android-support:x.y.z")
// With:
implementation("com.apollographql.apollo:apollo-normalized-cache-sqlite:x.y.z")
ApolloSqlHelper
is deprecated. Instantiate SqlNormalizedCacheFactory
with same arguments instead.
// Replace:
val apolloSqlHelper = ApolloSqlHelper.create(context, "db_name");
val cacheFactory = SqlNormalizedCacheFactory(apolloSqlHelper);
// With:
val cacheFactory = SqlNormalizedCacheFactory(context, "db_name");
Replace legacy Android SQL with SqlDelight (#2158)
Deprecated Gradle Plugin
The deprecated Gradle Plugin is now removed. Please refer to migration guide from previous releases before upgrading to 2.0 https://www.apollographql.com/docs/android/essentials/migration/#gradle-plugin-changes
Migrating to 1.3.x
Apollo Android version 1.3.0 introduces some fixes and improvements that are incompatible with 1.2.x. Updating should be transparent for simple use cases and your project should compile fine. If you're using more advanced features such as custom schema/graphql files location, Kotlin Gradle scripts and/or transformed queries, or if you encounter a build error after updating, read on for details about the changes.
Gradle plugin changes
The plugin has been rewritten in Kotlin to make it more maintainable and have better support for multiple GraphQL endpoints. Below are the main changes. Read plugin-configuration.md for a reference of the different options.
New plugin ID
The plugin ID has been changed from com.apollographql.android
to com.apollographql.apollo
to make it clear that the plugin works also
for non-Android projects. com.apollographql.android
will be removed in a future revision.
// Replace:
apply(plugin = "com.apollographql.android")
// With:
apply(plugin = "com.apollographql.apollo")
Using multiple services
The plugin now requires that you specify multiple services explicitly. If you previously had the following layout:
src/main/graphql/com/github/schema.json
src/main/graphql/com/github/GetRepositories.graphql
src/main/graphql/com/starwars/schema.json
src/main/graphql/com/starwars/GetHeroes.graphql
You will need to define 2 services:
apollo {
service("github") {
sourceFolder.set("com/github")
rootPackageName.set("com.github")
}
service("starwars") {
sourceFolder.set("com/starwars")
rootPackageName.set("com.starwars")
}
}
Specifying schema and GraphQL files location
The root schemaFilePath
, outputPackageName
and sourceSets.graphql
are removed and will throw an error if you try to use them. Instead
you can use [CompilationUnit] to control what files the compiler will use as inputs.
// Replace:
sourceSets {
main.graphql.srcDirs += "/path/to/your/graphql/queries/dir"
}
// With:
apollo { graphqlSourceDirectorySet.srcDirs += "/path/to/your/graphql/queries/dir"}
// Replace
apollo {
sourceSet {
schemaFilePath = "/path/to/your/schema.json"
exclude = "**/*.gql"
}
outputPackageName = "com.example"
}
// With:
apollo {
schemaFile.set(file("/path/to/your/schema.json"))
graphqlSourceDirectorySet.exclude("**/*.gql")
rootPackageName.set("com.example")
}
Kotlin DSL
The plugin uses Gradle Properties to support lazy configuration and wiring tasks together.
If you're using Groovy build.gradle
build scripts it should work transparently but Kotlin build.gradle.kts
build scripts will require
you to use the Property.set API:
apollo {
// Replace:
setGenerateKotlinModels(true)
// With:
generateKotlinModels.set(true)}
Also, the classes of the plugin have been split into an api
part and an internal
one. If you were relying on fully qualified class names from your build.gradle.kts
files, you will have to tweak them:
// Replace:
import com.apollographql.apollo.gradle.ApolloExtension
// With:
import com.apollographql.apollo.gradle.api.ApolloExtension
Breaking changes in generated Kotlin models with inline fragments:
Field inlineFragment
is no longer generated with a new Apollo 1.3.0 release for Kotlin models.
For example:
previous version of model with inline fragments
data class Hero(
val __typename: String,
/**
* The name of the character
*/
val name: String,
val inlineFragment: HeroCharacter?
) {
val asHuman: AsHuman? = inlineFragment as? AsHuman
val asDroid: AsDroid? = inlineFragment as? AsDroid
...
new version of generated model with inline fragments
data class Hero(
val __typename: String,
/**
* The name of the character
*/
val name: String,
val asHuman: AsHuman?,
val asDroid: AsDroid?
)
Motivation: there is an issue with previous version of generated model, there are cases when specified multiple inline fragments
should be resolved for the same GraphQL type. For example imagine that GraphQL schema defines this hierarchy of types
Character <- Hero <- Human
. Having this GraphQL query:
query {
character {
name
... on Hero { ... }
... on Human { ... }
}
}
both inline fragments on Hero
and on Human
should be resolved for character type Human
as Hero
is super type of Human
.
Previous version of generated model for Character
didn't resolve both inline fragments but rather first declared ... on Hero
. New
version resolves both fragments on Hero
and on Human
.
Migration:
If you have this code to get access to the resolved inline fragment:
when (hero.inlineFragment) {
is Hero.AsHuman -> // ...
is Hero.AsDroid -> // ...
}
you should change it to check all declared inline fragments for nullability, as it's possible now to have multiple resolved fragments:
if (hero.asHuman != null) {
// ...
}
if (hero.asDroid != null) {
// ...
}
Singularization
Singularization rules have been improved (see 1888). That means the name of some classes that were previously wrongly or badly singularized might have changed. Check for a generated class with a similar name if that happens.
Nested class names
Nested classes are now allowed to have the same name as their parent (see 1893). If you were previously using such a class, the numbered suffix will be removed.
Transformed queries removal
Version 1.3.0 can now optionally generate a operationOutput.json
file. This file will contain the generated queries source, operation name
and operation ID. You can use them to whitelist the operation on your server or any other use case. See
1841 for details.
Since operationOutput.json is a superset of the transformed queries, transformed queries have been removed. If you were using transformed queries, you will now have to use operationOutput.json.
Espresso Idling Resources
Idling Resources integration is moved to AndroidX! This is a potential breaking change for users who has not migrated to AndroidX yet. If you haven't you can still use the 1.2.x version in your test code.
The artifact is also renamed to make its intention more obvious. Documentation for idling resource can be found here
// Replace:
androidTestImplementation("com.apollographql.apollo:apollo-espresso-support:x.y.z")
// With:
androidTestImplementation("com.apollographql.apollo:apollo-idling-resource:x.y.z")