Skip to content

v4.0.0-alpha.3

Compare
Choose a tag to compare
@martinbonnin martinbonnin released this 08 Aug 17:26
· 463 commits to main since this release
fec1564

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) to ApolloClient.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)