Skip to content

Commit

Permalink
[📚doc] docs for 4.0.0-beta.5 (#5601)
Browse files Browse the repository at this point in the history
* update docs

* add HTTP headers docs

* Start drafting the changelog

* add compiler-plugin doc

* add doc for Apollo compiler plugins

* cosmetics

* cosmetics

* bump nullability in the next docs

* deprecate schemaFile

* dd all changes to the changelog

* use simple dependsOn() in docs

* add highlights

* bump nullability version

* This entry was part of the more general compiler plugins effort

* add 3.8.3 changelog

* remove 3.8.3 and add bullet points

* tweaks

* add links

* add link

* Update docs/source/advanced/compiler-plugins.mdx

Co-authored-by: Benoit 'BoD' Lubek <BoD@JRAF.org>

* Update docs/source/advanced/compiler-plugins.mdx

Co-authored-by: Benoit 'BoD' Lubek <BoD@JRAF.org>

* Update docs/source/advanced/compiler-plugins.mdx

Co-authored-by: Benoit 'BoD' Lubek <BoD@JRAF.org>

* use our own <Note>

* fix Note syntax

* better <Note> syntax

---------

Co-authored-by: BoD <BoD@JRAF.org>
  • Loading branch information
martinbonnin and BoD committed Mar 12, 2024
1 parent a91447f commit d1a7021
Show file tree
Hide file tree
Showing 7 changed files with 254 additions and 77 deletions.
75 changes: 75 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,81 @@
Change Log
==========

# Version 4.0.0-beta.5

_2024-03-12_

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` and `OperationOutputGenerator` are deprecated. See the [documentation page about Apollo compiler plugins](https://www.apollographql.com/docs/kotlin/v4/advanced/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](https://github.com/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](https://github.com/apollographql/specs/pull/42) and [apollographql/specs#48](https://github.com/apollographql/specs/pull/48)). If you are using `@semanticNonNull` or `@catch` you should bump your `@link` directives to use `0.3`. See the [nullability documentation page](https://www.apollographql.com/docs/kotlin/v4/advanced/nullability) 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](https://github.com/apollographql/apollo-kotlin/pull/5600))
* **Multi-version KDoc**: The [published KDoc](https://www.apollographql.com/docs/kotlin/kdoc/index.html) 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](https://github.com/apollographql/apollo-kotlin/pull/5694))
* [runtime] Implement NetworkMonitor for apple platforms ([#5691](https://github.com/apollographql/apollo-kotlin/pull/5691))
* [runtime] Add `NetworkMonitor` ([#5690](https://github.com/apollographql/apollo-kotlin/pull/5690))
* [runtime] Add `ApolloClient.retryOnError(Boolean)` ([#5685](https://github.com/apollographql/apollo-kotlin/pull/5685))
* [websockets-network-transport-incubating] Publish apollo-websocket-network-transport-incubating ([#5693](https://github.com/apollographql/apollo-kotlin/pull/5693))
* [normalized-cache-incubating] Use Store Cache and merge optimistic cache with Memory cache ([#5651](https://github.com/apollographql/apollo-kotlin/pull/5651))
* [runtime] Fix ApolloClient.Builder if the Builder is mutated by the caller after calling build() ([#5683](https://github.com/apollographql/apollo-kotlin/pull/5683))
* [websockets-network-transport-incubating] Introduce incubating WebSocketNetworkTransport ([#5678](https://github.com/apollographql/apollo-kotlin/pull/5678))
* [websockets-network-transport-incubating] Introduce incubating WebSocketEngine ([#5676](https://github.com/apollographql/apollo-kotlin/pull/5676))
* [runtime] Don't assume a single emission in AutoPersistedQueryInterceptor ([#5677](https://github.com/apollographql/apollo-kotlin/pull/5677))
* [runtime] Use expect funs instead of expect classes for DefaultHttpEngine ([#5672](https://github.com/apollographql/apollo-kotlin/pull/5672))
* [runtime] Fix JS websocket throws an ISE on error on Safari and Firefox ([#5670](https://github.com/apollographql/apollo-kotlin/pull/5670))
* [runtime] Use the streaming HttpEngine by default on Apple ([#5671](https://github.com/apollographql/apollo-kotlin/pull/5671))
* [intellij-plugin] Only send telemetry for Apollo Kotlin projects ([#5663](https://github.com/apollographql/apollo-kotlin/pull/5663))
* [gradle-plugin] Use Gradle normalization instead of ours ([#5636](https://github.com/apollographql/apollo-kotlin/pull/5636))
* [execution] Fix converting int and floats to their Kotlin value ([#5637](https://github.com/apollographql/apollo-kotlin/pull/5637))
* [runtime] Add ApolloClient.Builder(ApolloHttpCache) ([#5638](https://github.com/apollographql/apollo-kotlin/pull/5638))
* [gradle-plugin] Use com.android.lint Gradle rules ([#5639](https://github.com/apollographql/apollo-kotlin/pull/5639))
* [all] Update coroutines to 1.8.0 ([#5626](https://github.com/apollographql/apollo-kotlin/pull/5626))
* [runtime] Allow buildPostBody to write operation extensions ([#5630](https://github.com/apollographql/apollo-kotlin/pull/5630))
* [compiler] Add support for @catch on fieldDefinitions, interfaces and objects ([#5623](https://github.com/apollographql/apollo-kotlin/pull/5623))
* [all] Bump Kotlin to 2.0.0-Beta4 ([#5624](https://github.com/apollographql/apollo-kotlin/pull/5624))
* [normalized-cache-incubating] Cache lock changes ([#5608](https://github.com/apollographql/apollo-kotlin/pull/5608))
* [rx-support] Keep rx-support as DeprecationLevel.Error ([#5610](https://github.com/apollographql/apollo-kotlin/pull/5610))
* [gradle-plugin] Add dependsOn(dependencyNotation, bidirectional) ([#5606](https://github.com/apollographql/apollo-kotlin/pull/5606))
* [gradle-plugin] Fix a regression in alwaysGenerateTypesMatching where all types would be generated by default ([#5605](https://github.com/apollographql/apollo-kotlin/pull/5605))
* [️compiler] Add Apollo compiler plugin API ([#5604](https://github.com/apollographql/apollo-kotlin/pull/5604), [#5599](https://github.com/apollographql/apollo-kotlin/pull/5599), [#5591](https://github.com/apollographql/apollo-kotlin/pull/5591), [#5589](https://github.com/apollographql/apollo-kotlin/pull/5589), [#5588](https://github.com/apollographql/apollo-kotlin/pull/5588), [#5582](https://github.com/apollographql/apollo-kotlin/pull/5582), [#5573](https://github.com/apollographql/apollo-kotlin/pull/5573), [#5561](https://github.com/apollographql/apollo-kotlin/pull/5561), [#5560](https://github.com/apollographql/apollo-kotlin/pull/5560), [#5557](https://github.com/apollographql/apollo-kotlin/pull/5557), [#5556](https://github.com/apollographql/apollo-kotlin/pull/5556), [#5554](https://github.com/apollographql/apollo-kotlin/pull/5554), [#5516](https://github.com/apollographql/apollo-kotlin/pull/5516), [#5589](https://github.com/apollographql/apollo-kotlin/pull/5589))
* [intellij-plugin] Publish the IJ plugin snapshots to the JetBrain Marketplace ([#5600](https://github.com/apollographql/apollo-kotlin/pull/5600))
* [runtime] HTTP Headers: remove `X-APOLLO-OPERATION-NAME`, `X-APOLLO-OPERATION-ID` and the multipart boundary ([#5533](https://github.com/apollographql/apollo-kotlin/pull/5533))
* [gradle-plugin] use Worker API and ServiceLoader ([#5590](https://github.com/apollographql/apollo-kotlin/pull/5590))
* [gradle-plugin] deprecate schemaFile and sourceFolder ([#5581](https://github.com/apollographql/apollo-kotlin/pull/5581))
* [gradle-plugin] configuration cache and lazy properties for schema files ([#5580](https://github.com/apollographql/apollo-kotlin/pull/5580))
* [️compiler] Track semanticNonNull spec ([#5577](https://github.com/apollographql/apollo-kotlin/pull/5577))
* [gradle-plugin] bump minimum required Gradle version to 8.0 ([#5579](https://github.com/apollographql/apollo-kotlin/pull/5579))
* [ast] Validate repeatable directives ([#5574](https://github.com/apollographql/apollo-kotlin/pull/5574))
* [compiler] Don't automatically add key fields to union selections ([#5562](https://github.com/apollographql/apollo-kotlin/pull/5562))
* [runtime] Fix disabling batching by default ([#5552](https://github.com/apollographql/apollo-kotlin/pull/5552))
* [gradle-plugin] Select all types in pre-introspection query ([#5547](https://github.com/apollographql/apollo-kotlin/pull/5547))
* [normalized-cache-api] Remove unnecessary suspend from ApolloStore functions ([#5541](https://github.com/apollographql/apollo-kotlin/pull/5541))
* [all] One more step towards K2 but blocked on https://youtrack.jetbrains.com/issue/KT-21846 ([#5536](https://github.com/apollographql/apollo-kotlin/pull/5536))
* [all] Target Java17 for Android .aars and Java11 for apollo-gradle-plugin.jar ([#5534](https://github.com/apollographql/apollo-kotlin/pull/5534))
* [compiler] Remove old `generateAsInternal` code ([#5526](https://github.com/apollographql/apollo-kotlin/pull/5526))
* [compiler] Lock down apollo-compiler API ([#5524](https://github.com/apollographql/apollo-kotlin/pull/5524))
* [normalized-cache-sqlite] Use windowSizeBytes argument of AndroidSqliteDriver ([#5523](https://github.com/apollographql/apollo-kotlin/pull/5523))
* [intellij-plugin] Strip Apollo client directives before executing operations ([#5517](https://github.com/apollographql/apollo-kotlin/pull/5517))
* [execution] Fix converting GraphQL Float values to Kotlin ([#5511](https://github.com/apollographql/apollo-kotlin/pull/5511))
* [intellij-plugin] Don't show a visible task with progress bar while fetching the Apollo Conf ([#5501](https://github.com/apollographql/apollo-kotlin/pull/5501))
* [intellij-plugin] Inspection: missing directive import ([#5494](https://github.com/apollographql/apollo-kotlin/pull/5494))
* [intellij-plugin] Use recent version of slf4j to avoid a classloader issue ([#5495](https://github.com/apollographql/apollo-kotlin/pull/5495))
* [normalized-cache-sqlite] Allow custom SupportSQLiteOpenHelper.Callback in the SqlNormalizedCacheFactory ([#5488](https://github.com/apollographql/apollo-kotlin/pull/5488))
* [mockserver] Allow to set the content-type of String responses ([#5489](https://github.com/apollographql/apollo-kotlin/pull/5489))
* [debug-server] Start LocalServerSocket on background thread, and handle exception ([#5493](https://github.com/apollographql/apollo-kotlin/pull/5493))
* [cli-incubating] Publish apollo-cli-incubating again ([#5486](https://github.com/apollographql/apollo-kotlin/pull/5486))
* [intellij-plugin] Don't suggest v4 migration until it is stable ([#5477](https://github.com/apollographql/apollo-kotlin/pull/5477))
* [tooling] bump version of Apollo to `4.0.0-beta.3` ([#5452](https://github.com/apollographql/apollo-kotlin/pull/5452))
* [debug-server] Don't crash if ApolloDebugServerInitializer is not run (e.g. in unit tests) ([#5484](https://github.com/apollographql/apollo-kotlin/pull/5484))
* [intellij-plugin] Add debugging logs around the cache viewer ([#5475](https://github.com/apollographql/apollo-kotlin/pull/5475))
* [debug-server] Debug server: don't crash when a client has no caches ([#5479](https://github.com/apollographql/apollo-kotlin/pull/5479))
* [gradle-plugin] add apollo.deps ([#5460](https://github.com/apollographql/apollo-kotlin/pull/5460))

# Version 4.0.0-beta.4

_2023-12-12_
Expand Down
95 changes: 95 additions & 0 deletions docs/source/advanced/compiler-plugins.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
---
title: Apollo compiler plugins
---

The Apollo compiler supports [a wide range of options](../advanced/plugin-configuration). For the cases where these options are not enough, you can use Apollo compiler plugins to modify the behaviour of the compiler.

Apollo compiler plugins allow to:

* Change the layout of the generated sources (name of the classes, package names, capitalization rules).
* Change the ids of operation for persisted queries.
* Transform the JavaPoet/KotlinPoet models.
* Transform the Apollo IR.

# Implementing a compiler plugin

In this example we will implement a plugin that uses custom [persisted queries](../advanced/persisted-queries) ids registered on your backend.

The Apollo compiler use the [ServiceLoader API](https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html) to load plugins at runtime. Plugins need to be implemented in a separate module that is added to the classpath.

To start, create a new Gradle module and add `apollo-compiler` as a dependency to the module `build.gradle[.kts]` file. In this example, we'll use `apollo-compiler-plugin` for the module name:

```kotlin
// apollo-compiler-plugin/build.gradle.kts
plugins {
id("org.jetbrains.kotlin.jvm")
}

dependencies {
// Add apollo-compiler as a dependency
implementation("com.apollographql.apollo3:apollo-compiler:4.0.0-beta.4")
}
```

Next create your plugin in a `src/main/kotlin/mypackage/MyPlugin` file:

```kotlin
package mypackage

import com.apollographql.apollo3.compiler.OperationOutputGenerator
import com.apollographql.apollo3.compiler.Plugin
import com.apollographql.apollo3.compiler.operationoutput.OperationDescriptor
import com.apollographql.apollo3.compiler.operationoutput.OperationId

class MyPlugin: Plugin {
override fun operationIds(descriptors: List<OperationDescriptor>): List<OperationId> {
// This assumes the returned ids are in the same order as the descriptors
return registerOperations(descriptors).withIndex().map { OperationId(it.value, descriptors[it.index].name) }
}

/**
* Send operations to a remote server and return the server persisted ids
*/
fun registerOperations(descriptors: List<OperationDescriptor>): List<String> {
// ...
}
}
```

Make your plugin discoverable by [ServiceLoader](https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html) using a resource in `src/main/resources/META-INF/services/com.apollographql.apollo3.compiler.Plugin`. This file contains the fully qualified name of your plugin:

```
mypackage.MyPlugin
```

> [!NOTE]
> The name of the resource file is important. It must be `com.apollographql.apollo3.compiler.Plugin` and be in the `META-INF/services` folder. This is how `ServiceLoader` looks up `Plugins` at runtime.
# Adding a plugin to the Apollo compiler classpath

Use the `Service.plugin()` Gradle method to add the plugin to the Apollo compiler classpath:

```kotlin
// app/build.gradle.kts
plugins {
id("org.jetbrains.kotlin.jvm")
id("com.apollographql.apollo3")
}

apollo {
service("service") {
packageName.set("com.example")

// Add your plugin to the Apollo compiler classpath
plugin(project(":apollo-compiler-plugin")) // highlight-line
}
}
```

The plugin code will now be invoked the next time the compiler is invoked.

# Other references

For other plugin APIs like layout, IR, JavaPoet and KotlinPoet transforms, check out the [Plugin API docs](https://www.apollographql.com/docs/kotlin/kdoc/apollo-compiler/com.apollographql.apollo3.compiler/-plugin/index.html)

For more examples, check out the [integration-tests](https://github.com/apollographql/apollo-kotlin/tree/main/tests/compiler-plugins).
35 changes: 12 additions & 23 deletions docs/source/advanced/multi-modules.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ title: Multi Modules codegen

For multi-modules projects, Apollo Kotlin enables you to define queries in a feature module and reuse fragments and types from another module dependency. This helps with better separation of concerns and build times.

> Note: this page is for sharing a schema between different modules and defining your `.graphql` operations in different modules. If all your `.graphql` files are in a single module, you can use `ApolloClient` like any other Kotlin dependency without any of this.
<Note>
This page is for sharing a schema between different modules and defining your `.graphql` operations in different modules. If all your `.graphql` files are in a single module, you can use `apollo-runtime` like any other Kotlin dependency without any of this.
</Note>


## Setup
Expand Down Expand Up @@ -52,35 +54,22 @@ apollo {

By default, Apollo Kotlin generates all the types in your schema module. This is because there is no way to know in advance what types are going to be used by feature modules.

For large schemas, this can generate a lot of code and increase your build time significantly. In this case, you can opt in auto-detection of used types. This works by splitting the codegen task in different steps so that feature modules can let the schema module know what types are used before actually generating the models. To opt in, you need to add the "opposite" link by using `isADependencyOf()`:
For large schemas, this can generate a lot of code and increase your build time significantly. In this case, you can opt in auto-detection of used types. This works by splitting the codegen task in different steps so that feature modules can let the schema module know what types are used before actually generating the models. To opt in, call `dependsOn()` with the `bidirectional` argument set to true:

```kotlin
// schema/build.gradle.kts
apollo {
service("service") {
packageName.set("schema")
generateApolloMetadata.set(true)

// Get the used types from the downstream module
isADependencyOf(project(":feature1")) // highlight-line

// you can have several feature modules
isADependencyOf(project(":feature2"))
// ...
}
}
```

```kotlin
// feature1/build.gradle.kts
// feature/build.gradle.kts
apollo {
service("service") {
packageName.set("feature")
// Get the generated schema types (and fragments) from the upstream schema module
dependsOn(project(":schema")) // highlight-line

// Use `bidirectional` to have the schema module get the used types from this module
dependsOn(dependencyNotation = project(":schema"), bidirectional = true) // highlight-line
}
}
```

<Note>
The `bidirectional` parameter is experimental because it may break <a href="https://docs.gradle.org/current/userguide/build_environment.html">Gradle project isolation</a>. For a project-isolation compatible method, try <a href="https://www.apollographql.com/docs/kotlin/kdoc/apollo-gradle-plugin-external/com.apollographql.apollo3.gradle.api/-service/is-a-dependency-of.html">isADependencyOf</a>
</Note>

Once you opt in auto-detection of used types, it's important that **all** modules are doubly linked like above. If not the feature modules will fail to compile due to some missing schema classes.

0 comments on commit d1a7021

Please sign in to comment.