Releases: apollographql/apollo-kotlin
v4.0.0-beta.5
Main changes:
- Apollo compiler plugins: The GraphQL compiler now has APIs that you can use to customize the generated code. This can be used for changing visibility of some symbols, renaming them or more generally customizing the output for any advanced use cases. Moving forward, Apollo compiler plugins are the preferred way to customize operation IDs as well as package names and both
PackageNameGenerator
andOperationOutputGenerator
are deprecated. See the documentation page about Apollo compiler plugins for more details. - Reduced lock contention in apollo-normalized-cache-incubating: the incubating normalized cache now uses lock-free memory structures inspired by guava and MobileNativeFoundation/Store. We have seen improvements by up to 20% in some scenarios. Please share your numbers if you notice any positive (or negative) change.
- Nullability directives: The version of the supported nullability directives was bumped from 0.1 to 0.3 (See apollographql/specs#42 and apollographql/specs#48). If you are using
@semanticNonNull
or@catch
you should bump your@link
directives to use0.3
. See the nullability documentation page for more details. - New snapshot repository for the IntelliJ/Android Studio plugin: The repository to use for the weekly snapshots has changed. You can now use
https://go.apollo.dev/ij-plugin-snapshots
to get the latest weekly snapshots. (#5600) - Multi-version KDoc: The published KDoc now includes both v3 and v4 versions.
Many thanks to @ribafish, @molundb, @mboyd1993, @rohandhruva and @baconz for their help in this release 💙!
👷 All changes
- [mockserver] Add MockServer.enqueueError() and MockServer.assertNoRequest() (#5694)
- [runtime] Implement NetworkMonitor for apple platforms (#5691)
- [runtime] Add
NetworkMonitor
(#5690) - [runtime] Add
ApolloClient.retryOnError(Boolean)
(#5685) - [websockets-network-transport-incubating] Publish apollo-websocket-network-transport-incubating (#5693)
- [normalized-cache-incubating] Use Store Cache and merge optimistic cache with Memory cache (#5651)
- [runtime] Fix ApolloClient.Builder if the Builder is mutated by the caller after calling build() (#5683)
- [websockets-network-transport-incubating] Introduce incubating WebSocketNetworkTransport (#5678)
- [websockets-network-transport-incubating] Introduce incubating WebSocketEngine (#5676)
- [runtime] Don't assume a single emission in AutoPersistedQueryInterceptor (#5677)
- [runtime] Use expect funs instead of expect classes for DefaultHttpEngine (#5672)
- [runtime] Fix JS websocket throws an ISE on error on Safari and Firefox (#5670)
- [runtime] Use the streaming HttpEngine by default on Apple (#5671)
- [intellij-plugin] Only send telemetry for Apollo Kotlin projects (#5663)
- [gradle-plugin] Use Gradle normalization instead of ours (#5636)
- [execution] Fix converting int and floats to their Kotlin value (#5637)
- [runtime] Add ApolloClient.Builder(ApolloHttpCache) (#5638)
- [gradle-plugin] Use com.android.lint Gradle rules (#5639)
- [all] Update coroutines to 1.8.0 (#5626)
- [runtime] Allow buildPostBody to write operation extensions (#5630)
- [compiler] Add support for
@catch
on fieldDefinitions, interfaces and objects (#5623) - [all] Bump Kotlin to 2.0.0-Beta4 (#5624)
- [normalized-cache-incubating] Cache lock changes (#5608)
- [rx-support] Keep rx-support as DeprecationLevel.Error (#5610)
- [gradle-plugin] Add dependsOn(dependencyNotation, bidirectional) (#5606)
- [gradle-plugin] Fix a regression in alwaysGenerateTypesMatching where all types would be generated by default (#5605)
- [️compiler] Add Apollo compiler plugin API (#5604, #5599, #5591, #5589, #5588, #5582, #5573, #5561, #5560, #5557, #5556, #5554, #5516, #5589)
- [intellij-plugin] Publish the IJ plugin snapshots to the JetBrain Marketplace (#5600)
- [runtime] HTTP Headers: remove
X-APOLLO-OPERATION-NAME
,X-APOLLO-OPERATION-ID
and the multipart boundary (#5533) - [gradle-plugin] use Worker API and ServiceLoader (#5590)
- [gradle-plugin] deprecate schemaFile and sourceFolder (#5581)
- [gradle-plugin] configuration cache and lazy properties for schema files (#5580)
- [️compiler] Track semanticNonNull spec (#5577)
- [gradle-plugin] bump minimum required Gradle version to 8.0 (#5579)
- [ast] Validate repeatable directives (#5574)
- [compiler] Don't automatically add key fields to union selections (#5562)
- [runtime] Fix disabling batching by default (#5552)
- [gradle-plugin] Select all types in pre-introspection query (#5547)
- [normalized-cache-api] Remove unnecessary suspend from ApolloStore functions (#5541)
- [all] One more step towards K2 but blocked on https://youtrack.jetbrains.com/issue/KT-21846 (#5536)
- [all] Target Java17 for Android .aars and Java11 for apollo-gradle-plugin.jar (#5534)
- [compiler] Remove old
generateAsInternal
code (#5526) - [compiler] Lock down apollo-compiler API (#5524)
- [normalized-cache-sqlite] Use windowSizeBytes argument of AndroidSqliteDriver (#5523)
- [intellij-plugin] Strip Apollo client directives before executing operations (#5517)
- [execution] Fix converting GraphQL Float values to Kotlin (#5511)
- [intellij-plugin] Don't show a visible task with progress bar while fetching the Apollo Conf (#5501)
- [intellij-plugin] Inspection: missing directive import (#5494)
- [intellij-plugin] Use recent version of slf4j to avoid a classloader issue (#5495)
- [normalized-cache-sqlite] Allow custom SupportSQLiteOpenHelper.Callback in the SqlNormalizedCacheFactory (#5488)
- [mockserver] Allow to set the content-type of String responses (#5489)
- [debug-server] Start LocalServerSocket on background thread, and handle ...
v4.0.0-beta.4
✨ Initial Wasm support (#5458)
This release adds initial support for WebAssembly by adding the wasmJs
target.
Executing queries/mutations is working but this target is
experimental (Kotlin/Wasm is Alpha) and has multiple limitations:
- No WebSockets
- No caching
- No support for WASI or NodeJS
🪲 Bug fix
Downloading a schema from introspection (./gradlew downloadServiceSchemaFromIntrospection
) got broken in the previous release (#5449) and is now fixed.
👷 All changes
- [compiler] validate operation directives & enforce presence of the nullability directive definitions by @martinbonnin
in #5443 - [build] Bump okio version by @martinbonnin in #5447
- [build] Bump uuid version by @martinbonnin in #5448
- Fix 2nd step introspection by @BoD in #5451
- Add wasmJs target by @martinbonnin in #5458
- Add validation to check schema definitions are compatible with the bundled ones by @BoD
in #5444
v4.0.0-beta.3
Many thanks @chris-hatton and @sdfgsdfgd for contributing this version 💙
🧩 IDE plugin: in-memory cache support
The normalized cache viewer can now display the contents of your in-memory cache. To do so, it relies on a
debug server that you need to run in your debug builds:
val apolloClient = ApolloClient.Builder()
.serverUrl("https://example.com/graphql")
.build()
if (BuildConfig.DEBUG) {
ApolloDebugServer.registerApolloClient(apolloClient)
}
You can read more about it in the "Apollo debug server" documentation page.
🎣 Experimental @catch
and @semanticNonNull
support
@catch
makes it possible to model GraphQL errors as FieldResult
Kotlin classes giving you inline access to errors:
query GetUser {
user {
id
# map name to FieldResult<String?> instead of stopping the parsing
name @catch
avatarUrl
}
}
@semanticNonNull
is a better @nonnull
. @semanticNonNull
makes it possible to mark a field as null only on error. The matching Kotlin property is then generated as non-null:
# mark User.name as semantically non-null
extend type User @semanticNonNull(field: "name")
Both those directives are experimental and require opt-in of the nullability directives
You can read more about them in the "handle nullability" documentation page.
1️⃣ Experimental @oneOf
support
@oneOf
introduces input polymorphism to GraphQL:
input PetInput @oneOf {
cat: CatInput
dog: DogInput
fish: FishInput
}
input CatInput { name: String!, numberOfLives: Int }
input DogInput { name: String!, wagsTail: Boolean }
input FishInput { name: String!, bodyLengthInMm: Int }
type Mutation {
addPet(pet: PetInput!): Pet
}
With @oneOf
, only one of cat
, dog
or fish
can be set.
@oneOf
support is automatically enabled if your schema has the @oneOf
directive definition.
You can read more about it in the @oneOf
RFC
👷 All changes
[all] @oneOf
support (#5394, #5388)
[all] @catch
and @semanticNonNull
support (#5405)
[all] Take default values into account when computing field cache keys (#5384)
[all] Bump Kotlin to 2.0.0-Beta1 (#5373)
[IJ Plugin] Add 'Input class constructor issue' inspection (#5427)
[IJ plugin] Update v3->v4 migration following API tweaks (#5421)
[IJ Plugin] Report invalid oneOf
input object builder uses (#5416)
[IJ Plugin] Add inspection for @oneOf
input type constructor invocation (#5395)
[IJ plugin] Make the refresh button work with all normalized cache sources. (#5400)
[IJ Plugin] Cache viewer: take numbers into account in key sorting (#5396)
[IJ Plugin] Bump pluginUntilBuild to 233 (#5377)
[IJ Plugin] Telemetry: don't use a libraries changed listener (#5361)
[IJ Plugin] Cache viewer: add cache size to selector (#5357)
[IJ plugin] Use apollo-debug-server to retrieve normalized caches (#5348)
[IJ plugin] Cache viewer: "Pull from Device" modal dialog instead of action menu (#5333)
[IJ Plugin] Fix v3->v4 migration with ApolloCompositeException (#5330)
[runtime] remove some of the ApolloResponse.Builders (#5426)
[runtime] Add a few symbols as ERROR deprecation for the migration (#5422)
[runtime] Add executeV3 + toFlowV3 (#5417)
[runtime] Revive dataAssertNoErrors (#5419)
[runtime] Allow no data and no exception in case of GraphQL errors (#5408)
[runtime] Expose ExecutionContext to HttpEngine and add OkHttp helpers (#5383)
[runtime] Improve deprecation messages (#5411)
[runtime] Go back to just one Adapter class (#5403)
[runtime] Fix Optional.getOrElse (#5399)
[compiler] Remove kotlin-labs-0.1 directives (#5404)
[compiler] Throw a better exception than NullPointerException if a value is missing (#5402)
[compiler] ExecutableValidationResult is returned by validateAsExecutable() and cannot be @ApolloInternal (#5406)
[compiler] Rework the IrType hierarchy (#5392)
[compiler] remove CCN (#5387)
[compiler] Remove antlr (#5336)
[compiler] Tweak description javadoc, there is no need to use the same escaping as Kotlin (#5424)
[mockserver] Support setting port for Apollo MockServer (#5389)
[mockserver] Add WebSocket support to the MockServer (#5334)
[tools] Implement 2-step introspection (#5371)
[apollo-execution] Allow to pass arguments to the root types (#5352)
[apollo-ksp] Initial support for interfaces (#5351)
v4.0.0-beta.2
We're continuing to progress towards the stable release of Apollo Kotlin v4 with this 2nd beta, which contains a few bug fixes and a new normalized cache viewer in the IDE plugin.
This is a great time to try out the new version and report any issues you might find!
🧩 IDE plugin: normalized cache viewer
The IDE plugin now has a graphical tool to inspect a normalized cache database. It lets you browse the records and see their contents.
This is useful to debug cache issues, or to understand how the normalized cache works.
The tool is available from View
| Tool Windows
| Apollo Normalized Cache
.
More information about the plugin can be found here.
👷 All changes
- Fragment variables: fix false warning about unused variables (#5290)
- Fix reading fragment with include directives from the cache (#5296)
- Fix partial data throwing with useV3ExceptionHandling and normalized cache (#5313)
- Unbreak benchmarks (#5284)
- Bump to gradle 8.4 and IJGP 1.16.0 (#5286)
- Add apollo-execution and apollo-ksp (#5281)
- [IJ plugin] Normalized cache viewer: UI (#5298)
- Fix build (#5301)
- Bump to Kotlin 1.9.20-RC (#5300)
- [IJ plugin] Telemetry: networking (#5285)
- [IJ plugin] Cache viewer: record quick filter (#5302)
- Update release script to update versions in IJ plugin (#5303)
- MockServer API cleanup (#5307)
- Remove some warnings (#5308)
- Use the default hierarchy template (#5309)
- [IJ plugin] Cache viewer: open/read db file (#5306)
- [IJ plugin] Cache viewer: add back/forward buttons, and copy action (#5310)
- Fix NSURL tests on recent apple OSes (#5315)
- [IJ plugin] Cache viewer: pull file from attached devices (#5314)
- Make more of MockServer common code, only abstract the socket part (#5316)
v4.0.0-beta.1
The first beta of the next major version of Apollo Kotlin is here!
While there still may be a few API changes before the stable release, we are getting close and this is a great time to try out the new version and report any issues you might find!
💙️ External contributors
Many thanks to @baconz and @hbmartin for their awesome contributions to this release!
❗️ Schema Nullability Extensions (#5191)
The GraphQL community is working hard at making it easier to work with nullability in GraphQL.
In Apollo Kotlin, it is now possible to change the nullability of fields and list elements at the schema level using schema extensions. This is useful if you believe the schema made a field nullable for error reasons only and you don't want to handle those errors. In these cases, the whole query will return as an error.
Given the following SDL:
# schema.graphqls
type Query {
random: Int
list: [String]
required: Int!
}
You can extend it like so:
# extra.graphqls
extend type Query {
# make random non-nullable
random: Int!
# make list and list items non-nullable
list: [String!]!
# make required nullable
required: Int
# add a new field
new: Float
}
📜️ Code generation
generateMethods
option to control which model methods are generated (#5212)
By default all Kotlin models, operations, fragments, and input objects are generated as data classes. This means that the Kotlin compiler will
auto-generate toString
, equals
hashCode
, copy
and componentN
. If you don't think you need all of those
methods, and/or you are worried about the size of the generated code, you can now choose which methods to generate with the generateMethods
option:
apollo {
service("service") {
// Generates equals/hashCode
generateMethods.set(listOf("equalsHashCode"))
// Also generates toString, equals, and hashcode
generateMethods.set(listOf("equalsHashCode", "toString"))
// Only generates copy
generateMethods.set(listOf("copy"))
// Generates data classes (the default)
generateMethods.set(listOf("dataClass"))
}
}
Other codegen tweaks
Enum.values()
is no longer recommended when using Kotlin 1.9+ and the generated code now usesentries
instead (#5208)- Deprecation warnings in generated code are suppressed (#5242)
🧩 IntelliJ plugin
- You can now suppress reported unused fields, by adding a comment on the field, or by configuring a regex in the settings (#5195, #5197)
- Opening an operation in Sandbox now includes all referenced fragments (#5236)
🪲 Bug fixes
- Detect cyclic fragment references (#5229)
- Fix
Optional<V>.getOrThrow()
when V is nullable (#5192) useV3ExceptionHandling
only throws when there are no errors populated (#5231)- Tweak the
urlEncode
algorithm (#5234) - Add a validation for adding
keyFields
on non-existent fields (#5215) - Fix logging when the response body is a single line (#5254)
👷 All changes
- [Infra] Count tests in CI (#5181)
- Test: remove flake (#5167)
- Use compilations instead of multiple mpp targets for java codegen tests (#5164)
- [IJ plugin] Add fragment usages when going to fragment declaration (#5189)
- Add
mergeExtensions
andtoFullSchemaGQLDocument
(#5162) - Fix
Optional<V>.getOrThrow()
when V is nullable (#5192) - Schema Nullability Extensions (#5191)
- [IJ plugin] Add inspection suppressor to allow suppression on fields (#5195)
- Add PQL support to
registerOperations {}
(#5196) - Add WebSocketMockServer and tests for WebSocketEngine (#5187)
- [IJ plugin] Add options to ignore fields when reporting unused fields (#5197)
- Unbreak benchmarks (#5202)
- Bump uuid and okio (#5204)
- [IJ plugin] Update references to 4.0.0-alpha.2 to 4.0.0-alpha.3 (#5205)
- Use entries instead of values() when using Kotlin 1.9 (#5208)
- Add
generateMethods
options to control which methods are generated on "data" classes (#5212) - Add a validation for adding keyFields on non-existent fields (#5215)
- Engine tests: use compilations to share logic between ktor/default engines (#5216)
- Skip Dokka during development (#5219)
- Introduce JsonReader.toApolloResponse (#5218)
- Add tests for empty objects in last chunk (#5223)
- useV3ExceptionHandling should only throw when there are no errors populated (#5231)
- Tweak the urlencode algorithm (#5234)
- [IJ plugin] Gather referenced fragments when opening in Apollo Sandbox (#5236)
- Kotlin 1.9.20-Beta (#5232)
- Suppress Kotlin warnings in generated code (#5242)
- Add Optional.getOrElse(value) (#5243)
- Add Error.Builder() (#5244)
- Add APOLLO_RELOCATE_JAR and APOLLO_JVM_ONLY (#5245)
- Detect cyclic fragment references (#5229)
- [IJ plugin] Telemetry: collect properties (#5246)
- Bump kotlin to 1.9.20-Beta2 (#5249)
- [IJ plugin] Telemetry: settings and opt-out dialog (#5247)
- [IJ plugin] Telemetry: add IDE/plugin related properties and events (#5250)
- Fix cyclic fragment detection (#5252)
- [IJ plugin] Add an ErrorReportSubmitter (#5253)
- Logging a single line response body by @hbmartin in #5254
- [IJ plugin] Schedule send telemetry (#5256)
- Allow MapJsonReader to read non-Map instances (#5251)
- [IJ plugin] Fix a crash when loading plugin (#5260)
- Tweaks for K2 (#5259)
- Update apollo published (#5263)
v4.0.0-alpha.3
A lot of additions to the IntelliJ plugin as well as a new GraphQL parser, a new Ktor multiplatform engine and more!
💙 External contributors 💙
Apollo Kotlin wouldn't be where it is today without the awesome feedback, discussions and contributions from community members. Specifically in this release, we want to give a huge THANK YOU to: @Emplexx, @sonatard, @yt8492, @mayakoneval, @Meschreiber, @pcarrier and @ashare80
🧩 IntelliJ plugin
👓 Unused field inspection (#5069)
The IntelliJ plugin now detects unused fields in your queries and greys them out:
Screen.Recording.2023-07-06.at.15.15.13.mov
v4 migration
The IntelliJ plugin can migrate most of your codebase to v4. To try it out, go to:
Tools
-> Apollo
-> Migrate to Apollo Kotlin 4
Because Kotlin is such a rich language and we can't account for all possible ways to configure your build, you might have to do some manual tweaks after the migration. But the plugin should handle most of the repetitive tasks of migrating.
☁️ Schema download (#5143)
If you configured introspection, you can now download your schema directly from IntelliJ
📖 documentation
The IntelliJ plugin now has its own dedicated documentation page.
Consult it to find out everything you can do with the plugin as well as installation instructions.
🌳 Multiplatform Apollo AST (#5047)
Apollo AST, the GraphQL parser powering Apollo Kotlin is now a manually written recursive descent parser, compared to an automatically generated Antlr parser before.
Benchmarks show a x2 to x3 speed improvement and the parser also now supports all platforms Apollo Kotlin supports.
❗❓ Initial Client Controlled Nullability (CCN) support (#5118)
Client Controlled Nullability (CCN) is a GraphQL specification RFC aiming at making it easier to work with GraphQL in type safe languages like Kotlin and Swift.
To use CCN, use the !
and ?
CCN modifiers in your queries:
query GetUser {
user {
id
# name is required to display the user
name!
# phoneNumber is optional
phoneNumber?
}
}
The RFC is still in early stages and requires server support. The API and final shape of the RFC might still change. By adding support in Apollo Kotlin, we're hoping to unblock potential users and gather real life feedbacks helping the proposal move forward.
📡 Ktor engine (#5142)
Apollo Kotlin now ships a apollo-engine-ktor
that you can use to replace the default HTTP and WebSocket engines of ApolloClient. To use it, add apollo-engine-ktor
to your dependencies:
dependencies {
implementation("com.apollographql.apollo3:apollo-engine-ktor")
}
And configure your client to use it:
val apolloClient = ApolloClient.Builder()
.serverUrl("https://example.com/graphql")
.httpEngine(KtorHttpEngine())
.webSocketEngine(KtorWebSocketEngine())
.build()
👷 generateInputBuilders
(#5146)
For Kotlin codegen, Apollo Kotlin relied on constructors with default arguments. While this works well in most cases, default arguments lack the ability to distinguish between null
and absent
meaning you have to wrap your values in Optional
before passing them to your constructor. If you had a lot of values, it could be cumbersome:
val input = SignupMemberInput(
dob = Utils.changeDateFormat(user.dobMMDDYYYY, "MM/dd/yyyy", "yyyy-MM-dd"),
firstName = Optional.Present(user.firstName),
lastName = user.lastName,
ssLast4 = Optional.Present(user.ssnLastFour),
email = user.email,
cellPhone = Optional.Present(user.phone),
password = user.password,
acceptedTos = true,
formIds = Optional.Present(formIds),
medium = Optional.Present(ConsentMediumEnum.android)
)
To generate Kotlin Builders, set generateInputBuilders
to true in your Gradle file:
apollo {
service("api") {
packageName.set("com.example")
generateInputBuilders.set(true)
}
}
With Builders, the same above code can be written in a more fluent way:
val input = SignupMemberInput.builder().apply {
dob(Utils.changeDateFormat(user.dobMMDDYYYY, "MM/dd/yyyy", "yyyy-MM-dd"))
firstName(user.firstName)
lastName(user.lastName)
ssLast4(user.ssnLastFour)
email(user.email)
cellPhone(user.phone)
password(user.password)
acceptedTos(true)
formIds(formIds)
medium(ConsentMediumEnum.ANDROID)
}.build()
👷 All changes
- [IJ plugin] Update platformVersion to 223 (#5166)
- [runtime] Add Ktor Engine (#5142)
- [tests] Add a test for field names that have the same name as an enum type (#5158)
- [api] Remove limitation on the JSON nesting. If the JSON is way too nested, an OutOfMemory exception will happen (#5161)
- [ast] add HasDirectives to all things with directives (#5140)
- [compiler] add a test for types named
Object
(#5156) - [ast] Add a special comment to disable the GraphQL intelliJ plugin inspection (#5154)
- [IJ plugin] Inspection to suggest adding an introspection block (#5152)
- [compiler] Better KDoc escape (#5155)
- [ast] Allow explicit CCN syntax (#5148)
- [compiler] Add generateInputBuilders (#5146)
- [infra] Update KotlinPoet (#5147)
- [infra] update Gradle to 8.3-rc-3 (#5149)
- [IJ plugin] Add a Download Schema action (#5143)
- [runtime] Remove ChannelWrapper (#5145)
- [IJ Plugin] Suggest Apollo 4 migration from version catalog and build.gradle.kts dependencies (#5141)
- [IJ plugin] v3->v4 migration: add
useV3ExceptionHandling(true)
toApolloClient.Builder()
. (#5135) - [IJ plugin] Improve compat->operationBased migration (#5134)
- [IJ plugin] Avoid a crash caught in inspection (#5139)
- [ast] add GQLNamed and GQLDescribed on all types that have a name or a description (#5127)
- [ast] Omit scalar definitions from SDL (#5132)
- [infra] Use SQLDelight 2.0.0 (#5133)
- [IJ Plugin] Don't report redefinitions of built-in types as errors (#5131)
- [IJ plugin] v3 -> v4 migration: enum capitalization (#5128)
- [ast] Initial CCN support (#5118)
- [infra] Make generateSourcesDuringGradleSync opt-in now that we have the IJ plugin (#5117)
- [compose] Catch ApolloException in toState and watchAsState (#5116)
- [IJ plugin] v3 -> v4 migration: Gradle conf (#5114)
- [compiler] validate query/mutation/subscription directives (#5113)
- [cache] Move serialization outside of cache lock (#5101)
- [infra] Use compose 1.5.0 stable (#5108)
- [compiler] Fix "no schema found" error message (#5106)
- [IJ plugin] v3 -> v4 migration: deprecations/renames, part 2 (#5109)
- [infra] More Apollo AST APIs (#5104)
- [infra] Apollo AST: add start/end instead of endColumn/endLine (#5103)
- [IJ plugin] v3 -> v4 migration: deprecations/renames (#5099)
- [ast] fix column computation of block strings (#5102)
- [benchmarks] Add macrobenchmarks (#5100)
- [IJ plugin] Migrate to Apollo Kotlin 4: dependencies (#5097)
- [IJ plugin] Support IJ platform 232 (#5095)
- [infra] bump ijgp (#5091)
- [infra] remove a bunch of build workarounds (#5090)
- [4.0 cleanups] Remove DefaultImpls everywhere (#5088)
- [infra] Remove golatac (#5086)
- [infra] Use SQLDelight 2.0.0-rc02 and AGP 8.0.0 (#5085)
- [ast] Switch back the parser to Strings and add more tests (#5078)
- [benchmarks] add graphql-java benchmark (#5077)
- [infra] Use Kotlin 1.9.0 (#4997)
- [ast] Turn into a mpp module and move jmh benchmark to an integration test (#5072)
- [IJ/AS Plugin] Add unused operation and unused field inspections (#5069)
- [ast] add endLine/endColumn (#5064)
- [ast] Add more tests and rewrite the lexer to use bytes instead of strings (#5063)
- [IJ plugin] Add a test for ApolloFieldInsightsInspection (#5062)
- [IJ plugin] Add an "enclose in @defer fragment" quick fix for slow field inspection (#5061)
- [IJ plugin] Add "Schema in .graphql file" inspection (#5059)
- [ast] Add multiplatform apollo-ast (#5047)
- [IJ plugin] Distinguish Apollo v3 and v4 (#5056)
v4.0.0-alpha.2
A new alpha with updates to the IntelliJ/Android Studio plugin and better JS interop.
🧩Navigate to GraphQL
You can now navigate from Kotlin both GraphQL or Generated code:
03-go-to-declaration.mov
See blog the blog post and installation instructions for more information.
🧩Field insights
You can now connect the IJ/AS plugin to your GraphOS account. If your backend is configured to report field traces, the plugin will display a warning for expensive fields that may be slow to fetch.
You can configure it in your IJ/AS settings Languages & Frameworks
-> GraphQL
-> Apollo Kotlin
. See also #5048 for a video of the setup.
🌐@jsExport
responseBased
codegen can now generate models annotated with @jsExport. This allows to fetch your response using faster JS-only APIs and cast them to the generated models. See the JS interoperability documentation for more information. Many thanks to @baconz for the deep dive 💙
👷 All changes
- [IJ plugin] FieldInsights (#5034)
- [IJ plugin] Keep navigation working when using import aliases for operations and fragments (#5041)
- [IJ plugin] Make navigation more robust when gql elements are lowercase (#5037)
- Refactor custom scalar adapters (#4905)
- [IJ plugin] Add an 'Open in Apollo Sandbox' action (#5022)
- [IJ plugin] Update v3 version and codegen wording (#5015)
- add encodeDefaults to introspection schema serializer (#5016)
- Better error message for Kotlin objects that cannot be converted to JSON (#5011)
- Http cache: do not cache mutations (#5014)
- [IJ plugin] Find usages GQL -> Kotlin (#5006)
- [IJ plugin] Add GQL -> generated Kotlin navigation (#4999)
- [IJ plugin] Override GraphQL icons (#4980)
- add
Service.operationManifestFormat
(#4981) - [WebSockets] Fix fan out in websocket network transport (#4972)
- Throw inside flow in MapTestNetworkTransport (#4982)
- [IJ plugin] Add navigation to type declaration (cmd shift b) (#4978)
- [IJ plugin] Add navigation to input types / fields (#4968)
- Fix jsExport Gradle annotation mismatch (#4975)
- Generate response based code with jsExport (#4907)
- [IJ plugin] Navigate to enum declaration (#4965)
- remove Built-By attribute in generated jars (#4961)
v3.8.2
A maintenance release with bugfixes, mostly around WebSockets and subscriptions as well as a LocalTime adapter and options to work with operation manifests.
Huge THANK YOU to @baconz, @AlexHartford, @Oleur for the love they put in WebSocket contributions as well as @Jephuff for their first contribution 💙 .
👷 All changes
- add
Service.operationManifestFormat
(#4981) - WebSockets: Fix fan out in websocket network transport (#4972)
- Test: Throw inside flow in MapTestNetworkTransport (#4982)
- Doc: Add Optional.Absent in documentation (#4979)
- Doc: clarify that operationBased codegen is the recommendation (#4966)
- AST: use existing as the base for copying enum values (#4943)
- Cache: Fix deleting records in the SqlNormalizedCache with cascade-true (#4938)
- Compiler: Fix deprecated input field usage false positive (#4935)
- Doc: Clarify KDoc of
watch()
(#4914) - WebSockets: allow changing the serverUrl of WebSocketNetworkTransport (#4885)
- WebSockets: accept connectionPayload lambda instead of static auth (#4855)
- Add LocalTime adapter for Java and Kotlin (#4829)
- Doc: Add a section about the operationBased codegen (3.x) (#4940)
v4.0.0-alpha.1
This release is the first alpha of the next major version of Apollo Kotlin: 4.0.0.
This version is under development, but we want to give you a preview of what's coming, and get your early feedback. Please see the roadmap for more details about the release plan.
While version 3 changed a lot of APIs compared to version 2, version 4 should be mostly compatible with version 3. Version 4 will even keep the same package name in order to keep the number of changes low.
The error handling has changed but besides that, the version should be mostly compatible. Please consult the migration guide for all the details.
We would love to hear your feedback on this release. Please report any issues, questions, ideas, or comments on the issue tracker.
🛠️ Android Studio / IntelliJ plugin
See this page for installation instructions and more information.
This plugin for Android Studio and IntelliJ helps you work with Apollo Kotlin. It provides the following features:
- Automatic code generation
- Integration with the GraphQL IntelliJ Plugin
- Navigation to GraphQL definitions
- Helpers to migrate your project to the latest version
⚡️ ApolloResponse.exception
for error handling
Error handling is an important aspect of a client library and we found it could benefit from some changes.
In particular we are moving away from throwing exceptions:
- This improves dealing with Flows as they will no longer terminate on errors
- It helps grouping all error handling (network, GraphQL, caching) in the same area of your code
To that effect, there is now an ApolloResponse.exception : ApolloException
property, which will be present when a network error or cache miss have occurred, or when GraphQL errors are present:
val data = response.data
when {
data != null -> {
println("The server returned data: $data")
}
else -> {
// An error happened, check response.exception for more details or just display a generic error
when (response.exception) {
is ApolloGraphQLException -> // do something with exception.errors
is ApolloHttpException -> // do something with exception.statusCode
is ApolloNetworkException -> TODO()
is ApolloParseException -> TODO()
else -> // generic error
}
}
}
To ease the migration to v4, the v3 behavior can be restored by calling ApolloClient.Builder.useV3ExceptionHandling(true)
.
Feedback about this change is welcome on issue 4711.
☕️ apollo-runtime-java
for better Java support
As v3 has a Kotlin and Coroutines first API, using it from Java is sometimes impractical or not idiomatic. That is why in v4 we are introducing a new Java runtime, written in Java, which provides a Java friendly API. It is callback based and doesn't depend on a third-party library like Rx.
To use it in your project, instead of the usual runtime (com.apollographql.apollo3:apollo-runtime
), use the following dependency in your build.gradle[.kts]
file:
implementation("com.apollographql.apollo3:apollo-runtime-java")
Then you can use the ApolloClient
class from Java:
ApolloClient apolloClient = new ApolloClient.Builder()
.serverUrl("https://...")
.build();
apolloClient
.query(MyQuery.builder().build())
.enqueue(new ApolloCallback<MyQuery.Data>() {
@Override public void onResponse(@NotNull ApolloResponse<MyQuery.Data> response) {
System.out.prinitln(response.getData());
}
});
A few examples can be found in the tests.
🔃 Multi-module: automatic detection of used types
In multi-module projects, by default, all the types of an upstream module are generated because there is no way to know in advance what types are going to be used by downstream modules. For large projects this can lead to a lot of unused code and an increased build time.
To avoid this, in v3 you could manually specify which types to generate by using alwaysGenerateTypesMatching
. In v4 this can now be computed automatically by detecting which types are used by the downstream modules.
To enable this, add the "opposite" link of dependencies with isADependencyOf()
.
// schema/build.gradle.kts
apollo {
service("service") {
packageName.set("schema")
// Enable generation of metadata for use by downstream modules
generateApolloMetadata.set(true)
// More options...
// Get used types from the downstream module
isADependencyOf(project(":feature1"))
// You can have several downstream modules
isADependencyOf(project(":feature2"))
}
}
// feature1/build.gradle.kts
apollo {
service("service") {
packageName.set("feature1")
// Get the generated schema types (and fragments) from the upstream schema module
dependsOn(project(":schema"))
}
}