Version 2.5.8 adds support for Query Batching thanks to the awesome work of @joaquim-verges (#3117) 🙌 as well as reactor bindings made with 💙 by @aoudiamoncef (#3138). Thanks a lot for making Apollo Android better️!
Query batching collects multiple GraphQL queries happening in a short timeframe and sends them in a single HTTP call to a compatible server. This minimizes the number of HTTP calls, for an exemple when a new screen is displayed and multiple queries are sent at the same time.
To enable batching in your ApolloClient:
val apolloClient = ApolloClient.builder()
.serverUrl("https://")
.batchingConfiguration(
BatchConfig(
// enable batching
batchingEnabled = true,
// check queries every 20ms
batchIntervalMs = 20,
// or send as soon as there are 10 queries queued
maxBatchSize = 10
)
)
.build()
apolloClient.startBatchPoller()
Execute your queries:
val response = apolloClient.query(MyQuery())
.toBuilder()
.canBeBatched(true)
.build()
.await()
Stop batching:
apolloClient.stopBatchPoller()
Note: Enabling query batching reduces the number of HTTP calls but increases latency. Since the Batcher is run from a timer, an otherwise fast query will have to wait for both the timer to happen, and the backend to process all the events in the batch.
Project reactor is a reactive streams implementation for building non-blocking applications on the JVM. It's often used with Spring Boot for an example.
To add to your project:
// Reactor support
implementation("com.apollographql.apollo:apollo-reactor-support:x.y.z")
The usage is very similar to the RxJava2/RxJava3 bindings:
// Create Mono from a query
val mono = apolloClient.reactorQuery(query)
// Create Flux from a subscription
val flux = apolloClient.reactorSubscribe(subscription)
For more information, refer to the documentation.
apollo-runtime (#3117)Version 2.5.7 is built with Kotlin 1.5.0 and compatible with coroutines 1.5.0. It also fixes a regression while parsing defaultValues with Int values that should be coerced to Float and allows to change the buffering of MPP subscription messages thanks to the awesome work of @joaquim-verges (#3109) and @nealsanche (#3096)
1.5.0 supportVersion 2.5.6 exposes the Gradle plugin as a fat jar to workaround a long standing issue where older versions of okio and/or antlr would be loaded first in the classpath and override the versions required by the plugin (See #2287, #2359, #2886, #2939, #3022).
It does so by relocating and packaging the following dependencies inside apollo-gradle-plugin.jar:
The only functional change in this version is #3039 to include better exception messages, courtesy of @semaphore3000.
If you notice anything classloading-weird or if this doesn't work in your setup, please open an issue.
Version 2.5.5 is a maintenance release with support for ".graphqls" files and fixes in the Json parser and HTTP cache.
.graphqls files are now recognized as schema files (#2977)'\f') in json (#3006)Many thanks to @Romadro, @eduardb and @BRoy98 for their contributions!
Version 2.5.4 is a maintenance release. This version dropped Jcenter publishing and is the first one to be only available on Maven Central. It also contains some improvements around the Gradle plugin and codegen.
checkApolloVersions more lazy (#2935)ResponseFieldMapper when using delegates (#2945)Many thanks to @ansman and @lorensr for their contributions!
Version 2.5.3 is a maintenance release with improvements around codegen, runtime and cache.
Version 2.5.3 adds support for GraphQL RFC 373 (interfaces implementing interfaces). This makes sure the codegen understands interfaces implementing other interfaces and can compute the fragments possible types appropriately. It doesn't change the generated code.
Version 2.5.3 changes the Content-Type for apollo-runtime-kotlin from "aplication/json; charset=utf-8" to "application/json". This has been confusing spring servers and is the default json content type moving forward. If everything goes well, apollo-runtime will also switch to "application/json" in a future release. Read more in #2883. Many thanks to @vikrama for diving into this and fixing it.
Many thanks to @vikrama for fixing the content-type, to @AOrobator for making the Error and Location classes easier to debug, to @ansman for fixing Base64 on old Android versions, to @emmano for improving the documentation and @lwasyl for all the cache investigations!
Version 2.5.2 fixes a bunch of bugs and adds ApolloAndroidLogger and AppSyncOperationMessageSerializer. Huge thanks to @AdamMc331 and @ansman for their respective work on the logger and serializer 🙌 !
Note: version 2.5.2 is released from Github actions and that took a few iterations to get right. As a result, version 2.5.0 and 2.5.1 were not published and will never be.
ApolloAndroidLogger is a logger that will send its output to Logcat. Use it to display debug information on Android devices:
ApolloClient.builder()
.logger(ApolloAndroidLogger())
[...]
.build
AppSyncOperationMessageSerializer is a serializer that can understand the AWS AppSync message format. Pass it to your WebSocketSubscriptionTransport.Factory:
// This example uses an API key. See the AppSync documentation for information on what to pass
val authorization = mapOf(
"host" to "example1234567890000.appsync-api.us-east-1.amazonaws.com",
"x-api-key" to "da2-12345678901234567890123456"
)
val webSocketUrl = AppSyncOperationMessageSerializer.buildWebSocketUrl(
baseWebSocketUrl = "wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql",
authorization = authorization
)
val subscriptionTransportFactory = WebSocketSubscriptionTransport.Factory(
webSocketUrl = webSocketUrl,
webSocketConnectionFactory = okHttpClient,
serializer = AppSyncOperationMessageSerializer(authorization)
)
apolloClient.builder()
.subscriptionTransportFactory(subscriptionTransportFactory)
.build()
Version 2.4.6 is a minor release with fixes around multiplatform, normalized cache and others. Many thanks to @tylerbwong and @lwasyl for their work on the metalava integration and enum serialization respectively.
[Normalized cache] Add interface for classes generated for enum types and fix sealed classes json representation (#2776) [Multiplatform] fix NSURLSession configuration (#2777) [Test] adding test coverage (#2770) [Runtime] revert to okhttp 3 to support older versions of Android (#2769) [Gradle Plugin] make convertApolloSchema never up-to-date (#2761) [Multiplatform] Do not use Java8 Duration (#2767) [Build scripts] Fix error.NonExistentClass in Metalava Signature Files (#2755) [codegen] Honor packageName for schema types as well (#2759)
Version 2.4.5 is a minor release with Gradle plugin improvements for manipulating schemas as well as a few other bugfixes.
You can now convert your schema from Json to SDL and vice-versa:
./gradlew convertApolloSchema --from schema.json --to schema.sdl
You can now push a schema to your Apollo Studio registry:
./gradlew uploadApolloSchema --key $key --graph $graph --schema schema.sdl
[Gradle Plugin] add ./gradlew convertApolloSchema --from schema.json --to schema.sdl (#2757)
[Gradle plugin] Add pushApolloSchema (#2737)
[Publishing] add version and a few other attributes to the jar Manifest (#2736)
[Runtime] Introduce custom error class for better error handling (#2751)
[Codegen] Fix capitalized field names in input objects (#2746)
Version 2.4.4 is a hotfix release to disable using Kotlin parameters default values to represent GraphQL variables default values (#2741). This is not needed as the server can infer the variable default value from the query document and created a bunch of other issues (#2744 and #2742) in addition to sending uneeded variables alongside the query.
query GetHero($myBool: Boolean = true) { ... }
will now correctly generate
// no variable will be sent alongside the query by default
// and the server will read the default value from the GraphQL query document
data class GetHero(val myBool: Input<Boolean> = Input.absent())
This bug was introduced in version 2.4.2. If you're using GraphQL queries with variables default values, please upgrade to 2.4.4.
#2741 also fixes a crash in the handling of @include directives using variables default values in a much less invasive way. Many thanks to @DSteve595 for investigating this and pointing to the correct solution.
Version 2.4.3 is a minor version to fix a regression in ./gradlew downloadApolloSchema introduced in 2.4.2. The task would fail asking for a service even if schema and endpoint were correctly passed (See #2728 for more details).
Many thanks to @nicusorflorin for spotting this!
Other included fixes:
[SDL] better handling of string escapes (#2729) [KMP] added a 'timeoutMillis' parameter to ApolloHttpNetworkTransport (#2680)
Version 2.4.2 is a maintenance release with language improvements and fixes, better SQL cache debug, Websocket management and more.
Type extensions are now supported in SDL schemas. SDL schema can now include extension like below:
extend type Starship {
shieldLevel: Float!
}
Apollo Android now supports default values for variables (#2704)
query GetHero(
$myBool: Boolean = true,
$unit: LengthUnit! = FOOT,
$listOfInts: [Int] = [1, 2, 3]
) {
...
}
will generate:
data class GetHero(
val myBool: Input<Boolean> = Input.optional(true),
val unit: LengthUnit = LengthUnit.safeValueOf("FOOT"),
val listOfInts: Input<List<Int?>> = Input.optional(listOf(1, 2, 3))
)
This only works for scalar types and their list/nonnull declinations. Full support for input object will be added later. Follow #2572 for updates
SubscriptionManger.reconnect is now exposed as public API. It can be called to reconnect a WebSocket if credentials/token needs to be refreshed.
[Subscriptions] expose SubscriptionManager.reconnect() (#2706)
[Compiler] Add support for default variable values (#2704)
[SQL cache] implement SqlNormalizedCache.dump (#2709)
[SDL] add support for type extensions (#2666)
[Multi-modules] Add packageName option to override fragments package name (#2669)
[Compiler] fix @deprecated(reason:"") directive (#2720)
[Compiler] fix @deprecated directive without any deprecation reason (#2692)
[Gradle plugin] fix downloadApolloSchema variants detection (#2712)
[Compiler] support multiple arguments in directives (#2711)
[Compiler] Fix merging fields would forget inline fragments in some cases (#2689)
[Multiplatform] set the correct Content-Type on iOS (#2691)
[SDL] allow to have schemas without mutations/subscriptions (#2684)
[Gradle Plugin] Make CheckDuplicate task cacheable (#2688)
[Java codegen] Do not try to annotate primitive types in List type parameters (#2663)
[Compiler] Fix Missing Referenced Fragments in Root query type (#2647)
[Publishing] fix the license url and a few other dangling urls after the master -> (#2639)
[Documentation] use the correct "image/jpeg" mimetype. (#2699)
Many thanks to:
Version 2.4.1 brings a bunch of bug fixes, support for Gradle configuration cache and better Apollo Studio integration.
Apollo Android now supports Gradle configuration cache. Configuration cache is still an incubating Gradle feature. If you notice any warning in your builds, please file an issue
Users of Apollo Studio can now use the built-in ApolloClientAwarenessInterceptor to get more insights about their Android clients. Check the related documentation for more details how to do this.
Also, the Gradle plugin can now download schemas from the registry in addition to using introspection. To download a schema from the registry, use the --graph argument:
./gradlew downloadApolloSchema --graph $APOLLO_GRAPH --key $APOLLO_KEY --schema schema.[json | sdl]
[Gradle Plugin] add registry download (#2617) [Runtime] add a client awareness OkHttp interceptor (#2603) [Gradle Plugin] configuration cache compatibility (#2608)
[Compiler] fix line wrapping on long lines with forEach lambda. (#2621)
[Compiler] fix cache key for arguments that contain lists (#2592)
[Gradle Plugin] fix absolute paths in windows (#2615)
[Runtime] Fix some operation log calls (#2599)
Many thanks to @SamuelFrankSmith, @BenSchwab, @moshkit, @annieechen for their awesome work on codegen, runtime, documentation and help keep the project in good shape in general!
Version 2.4.0 brings multiple new features and bugfixes. Read below for the most important changes and full changelog
Version 2.4.0 brings Multi-Modules support. With Multi-Modules, you can reuse GraphQL fragments from different Gradle modules for better separation of concerns and improved build speed.
Configure your parent module to generate Apollo metadata:
// parent/build.gradle.kts
apollo {
generateApolloMetadata.set(true)
}
And declare your parent module as a dependency of your feature module:
// feature/build.gradle.kts
dependencies {
implementation("com.apollographql.apollo:apollo-runtime:xyz")
// more regular dependencies
// Apollo dependencies
apolloMetadata(project(":parent"))
// You still need to declare the parent module as a regular dependency
implementation(project(":parent"))
}
For more information, read the official documentation
⚠️ Multi-Modules is currently experimental and we'd love to hear how it worked (or not worked) for you. We welcome issues/feedback through the Github Issues
Version 2.4.0 brings even more fixes and tools to work with SDL schemas. SDL schemas are a more concise and readable way to work with GraphQL schemas. To use them, replace schema.json with your SDL schema schema.sdl. You can get a SDL schema from your GraphQL Playground if your endpoint has an associated Playground instance. If you don't have a playground instance or another way to download a SDL file, version 2.4.0 can make an introspection query and save it in SDL format. The schema will be saves as Json or SDL depending on the filename extension:
./gradlew downloadApolloSchema --endpoint https://your.graphql/endpoint --schema src/main/graphql/com/example/schema.sdl
If you're using apollo-coroutines-support, version 2.4.0 brings apolloCall.await() (#2574). It is more concise than the previous apolloCall.toDeferred().await() and also respects structured concurrency. We strongely encourage to move to .await(). Many thanks to @R4md4c for adding this!
The Kotlin 1.4.10 ecosystem is moving forward and we bumped a few dependencies (sqldeligh, okio, kotlin-compile-testing, coroutines and obviously kotlin).
The Gradle plugin is also compiled against Kotlin 1.4.10 despite Gradle forcing Kotlin 1.3.72 at runtime. We compile with apiVersion = "1.3" and our tests do not show any issue but please let us know if you see any weird Gradle behaviour.
Version 2.4.0 fixes how files were written in variables (#2566) and allows to subclass FileUpload to make it work without a File. With Android 11 and scoped storage out of the door, this will allow to upload from a content uri or any other data source. The API was inspired by OkHttp RequestBody. If you ever used OkHttp before, you shouldn't be disoriented:
object upload : FileUpload(mimetype) {
override fun contentLength(): Long {
TODO("return contentLength here")
}
override fun fileName(): String? {
TODO("return fileName to use in the multipart request here")
}
override fun writeTo(sink: BufferedSink) {
TODO("write the data here")
}
}
ApolloCall.await with better structured concurrency support. (#2574)retry() (#2587) Note that this is a behaviour change and this will clone the operation under the hood. If you were calling refetch() directly, you might need to update your calling code.main instead of master (#2594)Many thanks to @R4md4c, @dush1729, @jaggs6 for their awesome work on coroutines, documentation and keeping the project in good shape in general!
This is the Kotlin 1.4 release. It contains native binaries compiled for 1.4 and bumps some dependencies.
It also fixes ApolloCall.Builder.useHttpGetMethodForQueries, thanks a lot to @ubuntudroid for diving into this!
RealApolloCall.toBuilder() not respecting useHttpGetMethodForQueries (#2530)Enabling Auto Persisted Queries with ApolloClient.Builder.enableAutoPersistedQueries(true) will now enable mutations as well (#2509). This should cause no problem in the vast majority of cases. Server supporting auto persisted queries usually support auto persisted mutations as well. As a precautionary measure, we nonetheles recommend testing the integration with your server after upgrading.
The generated models and parsers can now target Javascript thanks to @andersio and @omainegra 💛. Check out the documentation for adding it to your multiplatform project. For runtime support, follow this issue.
In addition to OperationIdGenerator, you can now generate operation IDs in batch. This is useful if your backend requires a list of operations to whitelist that should be sent all at once.
Exemple usage:
// build.gradle.kts
apollo {
// ...
operationOutputGenerator.set(object : com.apollographql.apollo.compiler.OperationOutputGenerator {
// don't forget to bump the version if you change the implementation
override val version = "v1"
override fun generate(operationDescriptorList: Collection<OperationDescriptor>): OperationOutput {
return operationDescriptorList.associate {
it.source.md5() to it
}
}
})
}
toBuilder for ApolloMutationCall (#2501)defaultValue="null" for non-string scalar types (#2490)is for better java interop (#2474)Many thanks to @JakeSteam, @nymerias, @s1ee, @andersio, @omainegra and @olivierg13 for their awesome contributions!
Normalized cache performance improvements:
Continuing from version 2.2.2, this version adds even more cache performance improvements. For SqlNormalizedCache, reads are now wrapped in a transaction, which will make things faster, especially on large objects (#2422). You also have the option to opt-in asynchonous cache writes (#2416):
apolloClient.normalizedCache(cacheFactory, cacheKeyResolver, true)
Passing true for writeToCacheAsynchronously will make your UI display faster since it will get the network response without waiting for the cache write to happen.
SDL schema support:
Apollo Android now supports SDL (Schema Definition Language) for schemas (#2417). SDL is more concise and easier to read than the introspection json. To use it, place your SDL file in src/main/graphql/$some/$subdirectory/schema.sdl
ApolloClient.autoPersistedOperationsInterceptorFactory (#2420)com.apollo.compiler.VERSION (#2424)ApolloCall and add them on the Builder instead (#2434)Many thanks to @BenSchwab, @jeffnyauke, @DSteve595, @Shevatro and @baconz for their awesome contributions!
This release fixes an important performance issue with the multiplatform sql-normalized-cache-sqlite introduced in version 2.0.0. If you are using it, updating is strongly recommended. See #2412 for more details.
./gradlew downloadApolloSchema now resolves the schema path automatically if not specified (#2380)./gradlew publishToOssStagingIfNeeded (#2385)This version is a maintainance release to add the STORE_PARTIAL_RESPONSES cache header. Version 2.1.0 changed the caching behaviour to not store partial response if there are errors. This is the expected behaviour in the large majority of cases but some use cases might rely on this old behaviour. If you are in this case, you can now opt-in the previous behaviour with STORE_PARTIAL_RESPONSES. See #2363 for more details.
5A446C80C27E095353CF3969F165A96372E61948) instead of the default Bintray key before.This version, amongst other things, contains RxJava3 support, a new way to register ApolloInterceptor with factories and makes it easier to download your schema.json from the command line. Starting with this version, releases are published on Maven Central in addition to Jcenter.
Version 2.2.0 includes support for RxJava3. To use it, add the dependency to your Gradle file:
// RxJava3 support
implementation("com.apollographql.apollo:apollo-rx3-support:x.y.z")
The dependency contains static and extension methods to convert ApolloCall, ApolloSubscriptionCall, etc... to their RxJava3 counterparts.
For an exemple, to convert an ApolloCall to an Observable:
Java:
// Create a query object
EpisodeHeroName query = EpisodeHeroName.builder().episode(Episode.EMPIRE).build();
// Create an ApolloCall object
ApolloCall<EpisodeHeroName.Data> apolloCall = apolloClient.query(query);
// RxJava3 Observable
Observable<Response<EpisodeHeroName.Data>> observable3 = Rx3Apollo.from(apolloCall);
Kotlin:
// Create a query object
val query = EpisodeHeroNameQuery(episode = Episode.EMPIRE.toInput())
// Directly create Observable with Kotlin extension
val observable = apolloClient.rxQuery(query)
You can read more in the dedicated section of the documentation.
ApolloInterceptors added with ApolloClient.applicationInterceptor() were only created once for the lifetime of the ApolloClient so the same interceptor was always disposed. If you need your interceptor to start with a new state for each call, you can use ApolloInterceptorFactory that will create a new interceptor for each new call.
Using the downloadApolloSchema task from the command line is now easier:
# Instead of using properties:
./gradlew downloadApolloSchema -Pcom.apollographql.apollo.endpoint=https://your.graphql.endpoint \
-Pcom.apollographql.apollo.schema=src/main/graphql/com/example/schema.json
# You can now use `--endpoint` and `--schema`:
./gradlew downloadApolloSchema --endpoint=https://your.graphql.endpoint --schema=app/src/main/graphql/com/example/schema.json