A lot of additions to the IntelliJ plugin as well as a new GraphQL parser, a new Ktor multiplatform engine and more!
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
The IntelliJ plugin now detects unused fields in your queries and greys them out:
https://github.com/apollographql/apollo-kotlin/assets/372852/6a573a78-4a07-4294-8fa5-92a9ebb02e6c
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.
If you configured introspection, you can now download your schema directly from IntelliJ
<img src="https://github.com/apollographql/apollo-kotlin/assets/372852/3a15f587-b057-4df5-82c0-2e0b0247c203" width=250/>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.
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.
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.
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()
Object (#5156)useV3ExceptionHandling(true) to ApolloClient.Builder(). (#5135)Fetched April 11, 2026