Releases: apollographql/apollo-kotlin
v3.0.0-beta04
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 ba...
v2.5.11
Version 2.5.11
is a maintenance release with fixes for registerApolloOperations
and query batching.
💜 Many thanks to @AOrobator and @rocketraman for their awesome contributions and feedback !💜
👷 All Changes
- Added toString method for Input by @AOrobator in #3427
- Make safelistingHash closer to its apollo-tooling counterpart by @martinbonnin in #3471
- Make sure Response is always closed when batching by @martinbonnin in #3541
Full Changelog: v2.5.10...v2.5.11
v3.0.0-beta03
v3.0.0-beta02
This version introduces fluent APIs on operations, more multiplatform targets, more compatibility helpers
to ease transition from v2.x, and other fixes.
✨ [new and breaking] Fluent APIs (#3447)
The API to execute operations now uses the Fluent style, where you can chain method calls together. The ApolloClient
query
, mutate
and subscribe
methods now return an ApolloCall
that can be configured, and on which you can call execute
to execute the operation.
Before:
val request = ApolloRequest.Builder(HeroQuery()).fetchPolicy(FetchPolicy.NetworkOnly).build()
val response = apolloClient.query(request)
After (fluent):
val response = apolloClient.query(HeroQuery())
.fetchPolicy(FetchPolicy.NetworkOnly)
.execute()
If you were using cacheAndNetwork
, it's now executeCacheAndNetwork
:
// Before
apolloClient.cacheAndNetwork(query)
// After
apolloClient.query(query).executeCacheAndNetwork()
✨ [new] New multiplatform targets (#3487)
This release adds support for these new targets:
macosArm64
iosArm64
iosSimulatorArm64
watchosArm64
watchosSimulatorArm64
tvosArm64
tvosX64
tvosSimulatorArm64
Additionally, apollo-api
(models) is now compiled for linuxX64
. Follow this issue for updates on this - and contributions on this area are welcome!
✨ [new] Sealed interfaces in generated code (#3448)
When using the responseBased codegen, now interfaces will be generated as sealed
when possible.
Because sealed interfaces are only available since Kotlin 1.5, a new Gradle option languageVersion
has been introduced to control this behavior (and potentially future language features used by the codegen).
✨ [new] Version 2 compatibility helpers
To ease transition from 2.x, this release provides:
- a
CustomTypeAdapter
that can be used for custom scalars in the same way as in 2.x - an
Input
helper that will map to 3.xOptional
automatically
These helpers are deprecated and are to be used only as a temporary measure - they will be removed in a future version.
💙 External contributors
Thanks to @davidec-twinlogix, @pauldavies83 @nachtien and @Pitel for their awesome contributions!
👷 All Changes
- Add a "compat" v2 CustomTypeAdapter to v3 Adapter API (#3482)
- Add a few targets (#3487)
- Add parsing of non-standard Error fields (#3485)
- Resolve name clashes the same way as in 2.x (#3486)
- Make the packageName error more explicit for users that are migrating (#3477)
- Fix pointer use after free (#3478)
- Add Apple Silicon iOS Simulator Targets (#3481)
- Check minimum Kotlin version in the plugin (#3475)
- Migrate HttpRequest With-ers to Builders (#3474)
- Add .customScalarAdapter(CustomScalarAdapters) on ApolloClient.Builder (#3472)
- Bump KSP and Okio to stable 🎉 (#3473)
- [RFC] Fluent query API (#3447)
- Generate sealed interfaces in response based codegen (#3448)
- Add MySealedClass.knownValues() (#3465)
- Added Long support to RecordFieldJsonAdapter (#3468)
- Add an iOSX64 test and publish apollo-testing-support for ios (#3463)
- Add customTypesMapping for backward compatibility (#3452)
- Add Input backward compat layer (#3456)
- Rename include to includes (#3451)
v3.0.0-beta01
Version 3.0.0-beta01
is the first Beta release for Apollo Android 3 🎉. While there are no API stability guarantees just yet, 3.0.0-beta01
introduces binary compatibility validation to monitor the breaking changes and they should happen less frequently from now on.
One important API change in 3.0.0-beta01
is the change from with-ers to Builders. It also has a useVersion2Compat Gradle property to ease the transition from 2.x.
In addition, 3.0.0-beta01
introduces JavaScript runtime and cache support and new Test Builders APIs to generate fake data models.
💜 Many thanks to @Pitel and @dchappelle for the awesome additions to this release !💜
✨[new] JavaScript runtime and cache support (#3208)
Version 3.0.0-beta01
has support for JavaScript targets courtesy of @Pitel. It contains both IR and LEGACY artifacts. To use it in your builds, add apollo-runtime
and apollo-normalized-cache
dependencies to your build.gradle[.kts]
:
kotlin {
js(IR) { // or js(LEGACY)
sourceSets {
val commonMain by getting {
// To use HTTP and runtime
implementation("com.apollographql.apollo3:apollo-runtime:3.0.0-beta01")
// To use in-memory cache
implementation("com.apollographql.apollo3:apollo-normalized-cache:3.0.0-beta01")
}
}
}
}
This is everything needed. All the APIs work the same as their equivalent JVM/native ones.
Two caveats:
Contributions are very welcome, feel free to reach out on the kotlin lang slack to get started!
✨[new] Test Builders API (#3415)
You can now opt-in generation of Test Builders that make it easier to build fake models for your operations. Test Builders allow to generate fake data using a type safe DSL and provides mock values for fields so that you don't have to specify them all.
To enable Test Builders, add the below to your Gradle scripts:
apollo {
generateTestBuilders.set(true)
}
This will generate builders and add them to your test sourceSets. You can use them to generate fake data:
// Import the generated TestBuilder
import com.example.test.SimpleQuery_TestBuilder.Data
@Test
fun test() {
// Data is an extension function that will build a SimpleQuery.Data model
val data = SimpleQuery.Data {
// Specify values for fields that you want to control
hero = droidHero {
name = "R2D2"
friends = listOf(
friend {
name = "Luke"
}
)
// leave other fields untouched, and they will be returned with mocked data
// planet = ...
}
}
// Use the returned data
}
You can control the returned mock data using the TestResolver API:
val myTestResolver = object: DefaultTestResolver() {
fun resolveInt(path: List<Any>): Int {
// Always return 42 in fake data for Int fields
return 42
}
}
val data = SimpleQuery.Data(myTestResolver) {}
// Yay, now every Int field in `data` is 42!
✨🚧✨ [new and breaking] Version2 compatibility
3.0.0-beta01
introduces new Gradle options for better compatibility with versions 2. Most of the changes in this section can be reverted through configuration options but some had breaking side effects like valueOf
being renamed to safeValueOf
for enums.
sealedClassesForEnumsMatching
allows generating Kotlin enums for GraphQL enums.
Apollo 3.x generates sealed classes for Kotlin enums. As paradoxical as it may seem, sealed classes a better representation of GraphQL enums because they allow to expose the rawValue
of new enums that are not know at compile time. Sealed classes can also handle when
exhaustivity just like Kotlin enums and are generally more flexible. Using them may change the calling code though so as a temporary migration helper, you can now fallback to enum like in 2.x by setting sealedClassesForEnumsMatching
to an empty list instead of the default listOf(".*")
:
apollo {
sealedClassesForEnumsMatching.set(emptyList())
}
One side effect of this change is that the generated MySealedClass.valueOf()
has been renamed to MySealedClass.safeValueOf()
.
generateOptionalOperationVariables
allows wrapping your variables in Optional<>
.
By default Apollo Android 3 skips the Optional<>
wrapper for nullable variables. This simplifies the call site in the vast majority of cases where the variable is actually sent alongside the query.
There might be some rare occasions where you want to be able to omit a variable. For these cases, you can add an @optional
directive:
# a query that allows omitting before and/or after for bi-directional pagination
query MyQuery($before: String @optional, $after: String @optional) {
items {
title
}
}
If you have a lot of those queries, or if you prefer the 2.x behaviour, you can now opt-out globally:
apollo {
generateOptionalOperationVariables.set(true)
}
codegenModels
defaults to "operationBased"
3.0.0-beta01
now defaults to "operationBased"
models. "operationBased"
models match your GraphQL operations 1:1 and skip the extra .fragment
synthetic fields that are present in "compat"
models. Because they are simpler to understand, generate and execute, they are now the default. You can revert to "compat"
codegen with the codegenModels
Gradle option:
apollo {
codegenModels.set(MODELS_COMPAT)
}
useVersion2Compat()
For all these options, you can now fallback to the 2.x behaviour with useVersion2Compat()
. This is a shorthand function that configures the above options to match the 2.x behaviour. useVersion2Compat
is a helper to facilitate the migration and will be removed in a future update.
🚧[breaking] ApolloClient and ApolloRequest Builder APIs
Following the with-er vs Builder vs DSL RFC, we decided to move the main APIs to Builders. Builders are widely accepted, battle proven APIs that play nicely with Java and will make it easier to maintain Apollo Android in the long run.
While this beta-01
release keeps the with-ers
, they will be removed before Apollo Android 3 goes stable so now is a good time to update.
To build an ApolloClient
:
// Replace
val apolloClient = ApolloClient("https://com.example/graphql")
.withNormalizedCache(normalizedCacheFactory)
// With
val apolloClient = ApolloClient.Builder()
.serverUrl("https://com.example/graphql")
.normalizedCache(normalizedCacheFactory)
.build()
To build a ApolloRequest
:
// Replace
val apolloRequest = ApolloRequest(query)
.withFetchPolicy(FetchPolicy.CacheFirst)
// With
val apolloRequest = ApolloRequest.Builder(query)
.fetchPolicy(FetchPolicy.CacheFirst)
.build()
Websocket updates
The WebSocket code has been revamped to support client-initiated ping-pong for graphql-ws as well as a better separation between common code and protocol specific code.
A side effect is that WebSocket protocols are now configured using a WsProtocol.Factory:
// Replace
val apolloClient = ApolloClient(
networkTransport = WebSocketNetworkTransport(
serverUrl = "http://localhost:9090/graphql",
protocol = GraphQLWsProtocol()
)
)
// With
val apolloClient = ApolloClient.Builder()
.networkTransport(
WebSocketNetworkTransport(
serverUrl = "http://localhost:9090/graphql",
protocolFactory = GraphQLWsProtocol.Factory()
)
)
.build()
👷 All Changes
- Mutations over WebSocket (graphql-ws protocol) may hang indefinitely … by @dchappelle in #3383
- Fix nanosecond conversion on native by @martinbonnin in #3386
- Support Ping/Pong messages for graphql-transport-ws (#3291) by @dchappelle in #3401
- WebSockets: better separate common code and protocol-specific code by @martinbonnin in #3405
- Bump SqlDelight by @martinbonnin in #3407
- Bump Kotlin to 1.5.31 by @martinbonnin in #3414
- Allow isFromCache on all ApolloResponses by @martinbonnin in #3416
- Update ApolloClient and ApolloRequest APIs from With-ers to Builders by @BoD in #3404
- JavaScript by @Pitel in #3208
- Add Test Builders by @martinbonnin in https://github.com/apollographq...
v2.5.10
Version 2.5.10
is a maintenance release with a few bugfixes, mutiny support and a new Gradle register${VariantName}ApolloOperations
task to register your operations to the Apollo registry.
💜 Many thanks to @ProVir, @aoudiamoncef and @jgarrow for their contributions !💜
✨[new] Mutiny support (#3213)
Version 2.5.10
adds support for the Mutiny reactive library.
Add the dependency:
// Mutiny support
implementation 'com.apollographql.apollo:apollo-mutiny-support:x.y.z'
And convert your ApolloCall
to a Mutiny Uni:
// Create a query object
val query = EpisodeHeroNameQuery(episode = Episode.EMPIRE.toInput())
// Directly create Uni with Kotlin extension
val uni = apolloClient.mutinyQuery(query)
Read more in the documentation
✨[new] register${VariantName}ApolloOperations
(#3403)
If you're using Apollo safelisting, you can now upload the transformed operations from Gradle directly. Add a registerOperations {}
block to the apollo {}
block:
apollo {
service("service") {
registerOperations {
// You can get your key from https://studio.apollographql.com/graph/$graph/settings
key.set(System.getenv("APOLLO_KEY"))
graph.set(System.getenv("APOLLO_GRAPH"))
// Use "current" by default or any other graph variant
graphVariant.set("current")
}
}
}
Then call ./gradlew registerMainServiceApolloOperations
to register your operations to the registry. The operations will be registered including the added __typename
fields that might be added during codegen.
👷 All Changes
- refactor: RxJava2/3 support by @aoudiamoncef in #3166
- Remove duplicate ExecutionContext by @martinbonnin in #3213
- feat: add Mutiny support by @aoudiamoncef in #3198
- Updated coroutines for use native-mt version by @ProVir in #3330
- Increase Json nesting to 256 by @martinbonnin in #3334
- Give a hint at errorPayload by @martinbonnin in #3381
- Workaround wrong input field default values by @martinbonnin in #3398
- do not crash when trying to indent the GraphQL document by @martinbonnin in #3399
- Add ./gradlew push${MainService}ApolloOperations by @martinbonnin in #3403
- Operation Registry: normalize queries before computing the hash by @martinbonnin in #3406
New Contributors
- @ProVir made their first contribution in #3330
- @jgarrow made their first contribution in #3346
- @BoD made their first contribution in #3396
Full Changelog: v2.5.9...v2.5.10
v3.0.0-alpha07
Version 3.0.0-alpha07
has new builtin Adapters for java.time
, better custom scalar handling for multi module projects and multiple fixes for MPP and json parsers.
💜 Many thanks to @ProVir, @ychescale9 and @pauldavies83 for all the feedback and investigations !💜
✨[new] Adapters for java.time
Like there were adapters for kotlinx.datetime
, you can now use java.time
adapters from the apollo-adapters
package:
com.apollographql.apollo3.adapter.JavaInstantAdapter
com.apollographql.apollo3.adapter.JavaLocalDateAdapter
com.apollographql.apollo3.adapter.JavaLocalDateTimeAdapter
🚧[breaking] renamed kotlinx.datetime
Adapters
To keep things symmetrical with the java.time
adapters, the kotlinx.datetime
adapters are now named:
com.apollographql.apollo3.adapter.KotlinxInstantAdapter
com.apollographql.apollo3.adapter.KotlinxLocalDateAdapter
com.apollographql.apollo3.adapter.KotlinxLocalDateTimeAdapter
🚧[breaking] new LongAdapter
package name
Because LongAdapter
is widely used and doesn't require any additional dependencies, it is now in the builtin apollo-api package
// Replace
com.apollographql.apollo3.adapter.LongAdapter
// With
com.apollographql.apollo3.api.LongAdapter
👷 All Changes
- Fix OutOfBoundsException in MapJsonReader (#3375)
- Add Long support to JsonReader and JsonWriter (#3370)
- Fix structured concurrency issues dur to runCatching (#3364)
- add a convenience ApolloClient.apolloStore (#3367)
- simplify scalar handling (#3362)
- add java.time Adapters (#3360)
- relax freezing restrictions on the store (#3358)
v3.0.0-alpha06
Hotfix release to fix Android Studio autocomplete for generated files (#3354)
v3.0.0-alpha05
3.0.0-alpha05
is an incremental update on top of alpha04 with a few important fixes. Many thanks to all the feedback, in particular from @rickclephas, @ProVir, @ychescale9 and @james
on the Kotlinlang slack. Thank you 💜!
Relaxed freezing restrictions (#3350)
The Kotlin Native runtime was too strict in ensuring the Continuations
were never frozen, which caused exceptions when used with coroutines-native-mt
. This check has been removed.
Add ApolloClient.clearNormalizedCache (#3349)
To ease the transition from 2.x
, clearNormalizedCache
has been added as a deprecated function and will be removed for 3.1
Introduce __Schema to hold the list of all types (#3348)
Because only used types are generated in alpha04, we lost the ability to compute possible types in a typesafe way. This PR re-introduces this with an opt-it generateSchema
Gradle property:
apollo {
generateSchema.set(true)
}
This will:
- Force generate all composite types (interfaces, objects, unions)
- generate a
__Schema
class that will hold a list of all composite types
The __Schema
class has a possibleTypes()
function that can lookup possible types from the list of types:
assertEquals(
setOf(Cat.type, Dog.type, Crocodile.type),
__Schema.possibleTypes(Animal.type).toSet()
)
Fix custom scalars in multi module projects (#3341)
For multi-project builds, custom scalar were registered twice, leading to a validation error. This is now fixed.
v3.0.0-alpha04
3.0.0-alpha04
brings Java codegen and ApolloIdlingResource in Apollo Android 3. These were the final pieces that were not ported to Apollo Android 3 yet 🎉..
In addition, it brings some consistency improvements in the codegen/Gradle setup as well bump the max json stack size to 256 and other ergonomic improvements and fixes.
As we move towards a stable version, we'll have to settle for the current with-er
API or Builders
. Let us know what you think by letting a comment on the RFC.
✨[new] Java Codegen
Apollo Android 3 now generates Java models if the Kotlin plugin is not applied in your project. This is detected automatically and should work in the vast majority of cases. If you want to force Java codegen while still using the Kotlin plugin, you can set generateKotlinModels.set(false)
in your Gradle scripts:
apollo {
// Generate Java classes regardless of whether the Kotlin plugin is applied
generateKotlinModels.set(false)
}
Java models work like Kotlin models and use the same runtime. With the exception of default parameters, they are compatible with Kotlin operationBased
models so you can change the target language without having to update most of your code.
✨[new] apollo-idling-resource
apollo-idling-resource is now available in Apollo Android 3. You can include it with the apollo-idling-resource
artifact:
dependencies {
testImplementation("com.apollographql.apollo3:apollo-idling-resource:$version")
}
And create an ApolloClient
that will update the IdlingResource
:
val idlingResource = ApolloIdlingResource("test")
val apolloClient = ApolloClient("https://...")
.withIdlingResource(idlingResource)
✨[new] valueOf
for enums
Many thanks to @kubode for the contribution 💜
For GraphQL enums generated as sealed class, you can now call valueOf
to parse a String to a given enum value (or Unknown__ if unknown):
Given the below enum:
enum Direction {
NORTH,
EAST,
SOUTH,
WEST
}
You can use:
assertEquals(Direction.NORTH, Direction.valueOf("NORTH"))
assertEquals(Direction.Unknown__("NORTH-WEST"), Direction.valueOf("NORTH-WEST"))
✨[new] Platform errors for ApolloNetworkError
Many thanks to @ProVir for the help getting this done 💜
When something wrong happens during a network request, the runtime will throw a ApolloNetworkError
exception. You can now access the underlying platform error with ApolloNetworkError.platformCause
:
// On iOS you can cast to NSError
try {
apolloClient.query(query)
} catch (e: ApolloNetworkError) {
when ((e.platformCause as NSError?)?.domain) {
NSURLErrorDomain -> // handle NSURLErrorDomain errors ...
}
}
// On Android/JVM, platformCause is the same Throwable as Cause:
try {
apolloClient.query(query)
} catch (e: ApolloNetworkError) {
when (e.cause) {
is UnknownHostException -> // handle UnknownHostException errors ...
}
}
🚧[breaking] Mandatory package name
Because the default of an empty package name creates issues with kapt, it is now mandatory to set the package name of generated models:
apollo {
// Use the same packageName for all generated models
packageName.set("com.example")
// Or use a package name derived from the file location
packageNamesFromFilePaths()
}
🚧[breaking] Schema Types
For consistency, and in order to support multi-modules scenarios where some types are only generated in some modules, custom scalars, object and interface types are now generated as top-level classes in the .type
package name, like input objects and enums instead of being wrapped in a Types
object. Each schema type has a static type: CompiledType
property so you can access the type name in a type safe way.
// Replace
Types.Launch.name
// With
Launch.type.name
If you were using generated CustomScalarType
instances to register your custom scalar adapters, these are moved to the top level as well:
// Replace
ApolloClient("https://").withCustomScalarAdapter(Types.GeoPoint, geoPointAdapter)
// With
ApolloClient("https://").withCustomScalarAdapter(GeoPoint.type, geoPointAdapter)
🚧[breaking] Removed DefaultHttpRequestComposerParams
Because DefaultHttpRequestComposerParams
was setting multiple parameters at the same time (HTTP headers, method, etc..), setting one of them would overwrite a default set on the client. Instead of using DefaultHttpRequestComposerParams
, set parameters individually:
apolloClient.withHttpHeader("name", "value")
apolloRequest.withHttpHeader("otherName", "otherValue")
👷 All Changes
- Input array coercion (#3337)
- Java Codegen (#3335)
- bump the max stack size to 256 (#3333)
- Adds
valueOf
to the enum types (#3328) - Update to AGP 4.2 (#3324)
- bump Kotlin (#3319)
- Expose NSError (#3315)
- fix visibility of presentIfNotNull. (#3316)
- Add apollo-rx3-support (#3303)
- Move ApolloIdlingResource to apollo-idling-resource (#3302)
- simplify the Android setup (#3293)
- Make it possible to override ExecutionContext properties individually (#3294)
- Mandate package name (#3295)
- add more diagnostics for normalization failures (#3286)
- allow multiple HTTP headers with the same name (#3287)
- add error.path and error.extensions (#3285)
- Add 3.x ApolloIdlingResource (#3282)
- bump kotlin-compile-testing and enable warningsAsErrors again (#3278)
- add a way to disable Kdoc during development (#3279)
- Minor Cleanups (#3277)
- Simplify output dir connection (#3276)
- Remove split packages (#3275)
- Remove deprecated modules and move tests to the root level (#3274)
- Encode defaultValue as GraphQL value in introspection schemas (#3272)
- add a DefaultHttpNetworkTransport overload that takes a serverUrl (#3273)