This version is planned to be the last beta of Apollo Android 3 before a release candidate 🚀. It mainly focuses on stabilization and tweaks to the public API, makes it easier to work with the Java9 module system, and fixes a few issues.
⚙️ [breaking] API changes
Before going stable, we tweaked the public API to ensure consistency. The following methods have been renamed:
Before | After |
---|---|
ApolloClient.mutate()
| ApolloClient.mutation()
|
ApolloClient.subscribe()
| ApolloClient.subscription()
|
ApolloSubscriptionCall.execute()
| ApolloSubscriptionCall.toFlow()
|
In order to better support Java 9 and remove split packages, the following classes have been moved:
Before | After |
---|---|
com.apollographql.apollo3.cache.ApolloCacheHeaders
| com.apollographql.apollo3.cache.normalized.api.ApolloCacheHeaders
|
com.apollographql.apollo3.cache.CacheHeaders
| com.apollographql.apollo3.cache.normalized.api.CacheHeaders
|
com.apollographql.apollo3.cache.CacheHeaders.Builder
| com.apollographql.apollo3.cache.normalized.api.CacheHeaders.Builder
|
com.apollographql.apollo3.cache.CacheHeaders.Companion
| com.apollographql.apollo3.cache.normalized.api.CacheHeaders.Companion
|
com.apollographql.apollo3.cache.normalized.CacheKey
| com.apollographql.apollo3.cache.normalized.api.CacheKey
|
com.apollographql.apollo3.cache.normalized.CacheKey.Companion
| com.apollographql.apollo3.cache.normalized.api.CacheKey.Companion
|
com.apollographql.apollo3.cache.normalized.CacheKeyResolver
| com.apollographql.apollo3.cache.normalized.api.CacheKeyResolver
|
com.apollographql.apollo3.cache.normalized.CacheResolver
| com.apollographql.apollo3.cache.normalized.api.CacheResolver
|
com.apollographql.apollo3.cache.normalized.DefaultCacheResolver
| com.apollographql.apollo3.cache.normalized.api.DefaultCacheResolver
|
com.apollographql.apollo3.cache.normalized.FieldPolicyCacheResolver
| com.apollographql.apollo3.cache.normalized.api.FieldPolicyCacheResolver
|
com.apollographql.apollo3.cache.normalized.NormalizedCache.Companion
| com.apollographql.apollo3.cache.normalized.api.NormalizedCache.Companion
|
com.apollographql.apollo3.cache.normalized.NormalizedCacheFactory
| com.apollographql.apollo3.cache.normalized.api.NormalizedCacheFactory
|
com.apollographql.apollo3.cache.normalized.ReadOnlyNormalizedCache
| com.apollographql.apollo3.cache.normalized.api.ReadOnlyNormalizedCache
|
com.apollographql.apollo3.cache.normalized.Record
| com.apollographql.apollo3.cache.normalized.api.Record
|
com.apollographql.apollo3.cache.normalized.RecordFieldJsonAdapter
| com.apollographql.apollo3.cache.normalized.api.RecordFieldJsonAdapter
|
com.apollographql.apollo3.cache.normalized.MemoryCache
| com.apollographql.apollo3.cache.normalized.api.MemoryCache
|
com.apollographql.apollo3.cache.normalized.MemoryCacheFactory
| com.apollographql.apollo3.cache.normalized.api.MemoryCacheFactory
|
com.apollographql.apollo3.cache.normalized.OperationCacheExtensionsKt
| com.apollographql.apollo3.cache.normalized.api.OperationCacheExtensionsKt
|
Other renames
Before | After |
---|---|
com.apollographql.apollo3.api.ApolloExperimental
| com.apollographql.apollo3.annotations.ApolloExperimental
|
com.apollographql.apollo3.api.ApolloInternal
| com.apollographql.apollo3.annotations.ApolloInternal
|
com.apollographql.apollo3.cache.normalized.ObjectIdGenerator
| com.apollographql.apollo3.cache.normalized.api.CacheKeyGenerator
|
com.apollographql.apollo3.cache.normalized.ObjectIdGeneratorContext
| com.apollographql.apollo3.cache.normalized.api.CacheKeyGeneratorContext
|
com.apollographql.apollo3.network.http.OkHttpEngine
| com.apollographql.apollo3.network.http.DefaultHttpEngine
|
Renames in ApolloCall and ApolloClient (#3594)
ApolloClient
's mutate
and subscribe
methods have been renamed to mutation
and subscription
respectively. This
creates a more consistent API by reusing the GraphQL specification terminology.
Also, mutate()
, subscribe()
could be misleading as despite being verbs, no action is done until execute()
is
called. Using mutation()
/subscription()
hints that execute()
is required as a terminal operation.
// Before
val data = client.mutate(MyMutation()).execute()
// After
val data = client.mutation(MyMutation()).execute()
Also, ApolloSubscriptionCall.execute()
has been renamed to ApolloSubscriptionCall.toFlow()
to make it clearer that it
returns a cold Flow
that can be collected several times:
// Before
val flow = client.subscription(MySubscription).execute()
// After
val flow = client.subscription(MySubscription).toFlow()
Rename ObjectId to CacheKey (#3575)
CacheKeys
were sometimes referred to as Cache ids
, Object ids
, despite all of them being the same concept (the key
of an object in the cache). For consistency inside the Apollo Android codebase and with the iOS and Web
clients, CacheKey
is going to be used everywhere moving forward
// Before
val objectIdGenerator = object : ObjectIdGenerator {
override fun cacheKeyForObject(obj: Map<String, Any?>, context: ObjectIdGeneratorContext): CacheKey? {
// Retrieve the id from the object itself
return CacheKey(obj["id"] as String)
}
}
val apolloClient = ApolloClient.Builder()
.serverUrl("https://...")
.normalizedCache(
normalizedCacheFactory = cacheFactory,
objectIdGenerator = objectIdGenerator,
)
.build()
// After
val cacheKeyGenerator = object : CacheKeyGenerator {
override fun cacheKeyForObject(obj: Map<String, Any?>, context: CacheKeyGeneratorContext): CacheKey? {
// Retrieve the id from the object itself
return CacheKey(obj["id"] as String)
}
}
val apolloClient = ApolloClient.Builder()
.serverUrl("https://...")
.normalizedCache(
normalizedCacheFactory = cacheFactory,
cacheKeyGenerator = cacheKeyGenerator,
)
.build()
dataAssertNoErrors
(#3534)
To reflect more accurately what this method does, dataOrThrow
is now dataAssertNoErrors
.
Kotlin enums generation by default (#3551)
Apollo Android can either generate GraphQL enums as Kotlin enums or sealed classes. In previous 3.0 releases, the
default was to generate sealed classes but it is now enums, as this will be more expected, works better with Swift, and
is consistent with the 2.x behavior. To fallback to the previous behaviour of always generating sealed classes, use the sealedClassesForEnumsMatching
Gradle option:
apollo {
sealedClassesForEnumsMatching.set(listOf(".*"))
}
Improve java usability (#3576 and #3509)
Using Apollo Android from Java should be less cumbersome thanks to a few API tweaks in this release. For example, to set
up a normalized cache:
// Before
builder = ClientCacheExtensionsKt.normalizedCache(
builder,
new MemoryCacheFactory(10 * 1024 * 1024, -1),
TypePolicyObjectIdGenerator.INSTANCE,
FieldPolicyCacheResolver.INSTANCE,
false
);
// After
NormalizedCache.configureApolloClientBuilder(
builder,
new MemoryCacheFactory(10 * 1024 * 1024, -1),
);
Other noteworthy tweaks (#3509, #3538, #3557, #3598)
HttpNetworkTransport
andWebSocketNetworkTransport
now use the Builder pattern for instantiationFlowDecorator
have been removed fromApolloClient
asApolloInterceptor
can be used insteadhttpHeader
extension is nowaddHttpHeader
- We also made sure with this release that classes that are not meant to be used outside the library are marked as
internal.
✨ [new] Java Platform Module System (JPMS) support (#3558)
Apollo Android now publishes jar files containing the Automatic-Module-Name
property and non-split packages. This
change makes it easier to work with Apollo Android from a Java 9+ modularized application.
✨ [new] Add fallback adapters (#3582)
You no longer need to register any of the built-in adapters after declaring a custom scalar type that maps to a built-in
type (Int, Long, String, etc.).
For instance, when declaring this custom scalar type:
apollo {
customScalarsMapping = [
"MyCustomNumber": "kotlin.Long"
]
}
There is no need to call addCustomScalarAdapter
on the builder anymore, as since it is for a kotlin.Long
it will
automatically fall back to the built-in LongAdapter
.
🪲 [fixes] Optimistic cache and Gradle plugin (#3577, #3496)
- Fix an issue where the optimistic cache data was not reverted when an error happens
- The Gradle plugin now correctly works without the Kotlin Plugin
👷 All Changes
- make Guard and NonMainWorker internal (#3600)
- Tweak visibility of apollo-api symbols (#3598)
- Make a few classes internal (#3591)
- Make a few classes either internal or @ApolloInternal (#3590)
- Check internal on http-cache (#3589)
- Renames in ApolloCall and ApolloClient (#3594)
- Add apollo-annotations (#3588)
- Add fallback adapters (#3582)
- Merge main in dev-3.x (#3580)
- Improve java usability (#3576)
- Optimistic cache fixes (#3577)
- Add 2.x compat mode for useHttpGetMethodForQueries and useHttpGetMethodForPersistedQueries (#3578)
- Rename ObjectId to CacheKey (#3575)
- Handle experimental opt ins (#3565)
- Kotlin 1.6 (#3563)
- JPMS support (#3558)
- Rename httpHeader extensions to addHttpHeader (#3557)
- Go back to generating GraphQL enums as Kotlin enums by default (#3551)
- Relocate the kotlin-stdlib in the Gradle Plugin (#3542)
- Add "UI testing" and remove flowDecorators (#3538)
- Allow Delete/Continue/Replace during AST transformations (#3545)
- Tweak the errors doc and add ApolloResponse.dataAssertNoErrors (#3534)
- update Gradle and wrapper to 7.3 (#3535)
- Mark Test Builders are experimental (#3511)
- Add more Builders and other API tuning ✨ (#3509)
- Make the Gradle plugin work without the Kotlin Plugin (#3496)