Skip to content

Commit 371b662

Browse files
BoDmartinbonnin
andauthored
Documentation tweaks and updates for v4 (#5954)
* Documentation tweaks * Update docs/source/caching/normalized-cache.mdx Co-authored-by: Martin Bonnin <[email protected]> * Address a few review comments * Address a few review comments * Revert "cache ID" -> "cache key" --------- Co-authored-by: Martin Bonnin <[email protected]>
1 parent 9f885df commit 371b662

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+340
-304
lines changed

.idea/codeStyles/Project.xml

Lines changed: 5 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/source/_redirects

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@
1919
/advanced/test-builders/ /docs/kotlin/testing/test-builders/
2020
/advanced/response-based-codegen/ /docs/kotlin/advanced/response-based/
2121
/advanced/codegen-methods/ /docs/kotlin/advanced/response-based/
22+
/advanced/source-sets/ /docs/kotlin/advanced/plugin-configuration/#wiring-generated-sources

docs/source/advanced/apollo-ast.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: Apollo AST
44

55
To generate client code, Apollo Kotlin parses both your GraphQL schema _and_ each operation you write against it into an **Abstract Syntax Tree** ([AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree)). An AST represents a GraphQL document in a type-safe, machine-readable format.
66

7-
Apollo Kotlin's parser has its own module (`apollo-ast`), which you can use independently of `apollo-runtime` or `apollo-api`.
7+
The Apollo Kotlin parser has its own artifact (`apollo-ast`), which you can use independently of `apollo-runtime` or `apollo-api`.
88

99
Features of `apollo-ast` include:
1010

@@ -29,7 +29,7 @@ dependencies {
2929

3030
Use the `parseAsGQLDocument` method to parse a document from a `File`, a `String`, or an Okio [`BufferedSource`](https://square.github.io/okio/3.x/okio/okio/okio/-buffered-source/index.html).
3131

32-
```kotlin {12}
32+
```kotlin {13}
3333
val graphQLText = """
3434
query HeroForEpisode(${"$"}ep: Episode) {
3535
hero(episode: ${"$"}ep) {

docs/source/advanced/authentication.mdx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
title: Authenticate your operations
33
---
44

5-
> Authentication is not included in the GraphQL specification. This page aims at giving some guidance for the most common scenarios but doesn't pretend to be exhaustive.
5+
> Authentication is not included in the GraphQL specification. This page aims at giving some guidance for the most common scenarios but doesn't intend to be exhaustive.
66
77
## Authenticating your HTTP requests with OkHttp
88

99
[OkHttp Interceptors](https://square.github.io/okhttp/features/interceptors/) are an easy way to add an `"Authorization"` header to your HTTP requests.
1010

11-
OkHttp Interceptors have been around for a long time and work well but only work on Android and the JVM.
11+
OkHttp Interceptors have been around for a long time and work well but can only be used with Apollo Kotlin on Android and the JVM.
1212

1313
## Authenticating your HTTP requests with Apollo HttpInterceptor
1414

@@ -69,10 +69,10 @@ Alternatively, you can also send headers in the initial WebSocket handshake requ
6969

7070
```kotlin
7171
val apolloClient = ApolloClient.Builder()
72-
.httpServerUrl("http://localhost:8080/graphql")
72+
.httpServerUrl("https://example.com/graphql")
7373
.subscriptionNetworkTransport(
7474
WebSocketNetworkTransport.Builder()
75-
.serverUrl("http://localhost:8080/subscriptions")
75+
.serverUrl("https://example.com/subscriptions")
7676
.addHeader("Authorization", authorization) // highlight-line
7777
.build()
7878
)
@@ -83,7 +83,11 @@ val apolloClient = ApolloClient.Builder()
8383

8484
When using authenticated subscriptions over WebSockets, you might want to refresh your authentication token because it was invalidated or simply because it expired.
8585

86-
> Note: if your user logged out, you might want to consider creating a new `ApolloClient` instead. This will make sure that all other state besides the WebSocket, like cache for an example, is new and not shared amongst different users.
86+
<Note>
87+
88+
If your user logged out, you might want to consider creating a new `ApolloClient` instead. This will make sure that all other state besides the WebSocket, like cache for an example, is new and not shared amongst different users.
89+
90+
</Note>
8791

8892
Sometimes the websocket will emit an error that you can use in `webSocketReopenWhen` to create a new WebSocket. Other times that information will come from elsewhere in your app and you will have to force disconnect the WebSocket.
8993

docs/source/advanced/client-awareness.mdx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ GraphOS Studio users can opt-in [Client Awareness](https://www.apollographql.com
66

77
Client Awareness uses `apollographql-client-name` and `apollographql-client-version` custom HTTP headers to report client usage.
88

9-
Enable it by adding an `ApolloClientAwarenessInterceptor` to your `OkHttpClient`:
9+
Enable it by adding an `ApolloClientAwarenessInterceptor` to your `ApolloClient`:
1010

1111
```kotlin
1212
val apolloClient = ApolloClient.Builder()
@@ -15,4 +15,6 @@ val apolloClient = ApolloClient.Builder()
1515
.build()
1616
```
1717

18-
**Note**: This example uses `BuildConfig` to set the applicationId as client name and app version as client version but you can override this. Especially, if your iOS and Android apps use the same package name, it's useful to customize it to allow differentiating the clients
18+
<Note>
19+
This example uses `BuildConfig` to set the app's `applicationId` as the client name and its `versionName` as the client version, but you can override this. Especially, if your iOS and Android apps use the same package name, it's useful to customize it to be able to differentiate the clients.
20+
</Note>

docs/source/advanced/compiler-plugins.mdx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22
title: Apollo compiler plugins
33
---
44

5+
<ExperimentalFeature>
6+
7+
**Compiler plugins are currently [experimental](https://www.apollographql.com/docs/resources/release-stages/#experimental-features) in Apollo Kotlin.** If you have feedback on them, please let us know via [GitHub issues](https://github.com/apollographql/apollo-kotlin/issues/new?assignees=&labels=Type%3A+Bug&template=bug_report.md) or in the [Kotlin Slack community](https://slack.kotl.in/).
8+
9+
</ExperimentalFeature>
10+
511
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.
612

713
Apollo compiler plugins allow to:
@@ -140,6 +146,6 @@ Because codegen is run in a separate classloader when using compiler plugins, it
140146

141147
## Other references
142148

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

145151
For more examples, check out the [integration-tests](https://github.com/apollographql/apollo-kotlin/tree/main/tests/compiler-plugins).

docs/source/advanced/experimental-websockets.mdx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
---
2-
title: Experimental websockets
2+
title: Experimental WebSockets
33
---
44

5-
> ⚠️ **Experimental websockets APIs are [experimental](https://www.apollographql.com/docs/resources/release-stages/#experimental-features) in Apollo Kotlin.** If you have feedback on them, please let us know via [GitHub issues](https://github.com/apollographql/apollo-kotlin/issues/new?assignees=&labels=Type%3A+Bug&template=bug_report.md&title=[Defer%20Support]) or in the [Kotlin Slack community](https://slack.kotl.in/).
5+
<ExperimentalFeature>
66

7+
**The experimental WebSockets implementation are currently [experimental](https://www.apollographql.com/docs/resources/release-stages/#experimental-features) in Apollo Kotlin.** If you have feedback on them, please let us know via [GitHub issues](https://github.com/apollographql/apollo-kotlin/issues/new?assignees=&labels=Type%3A+Bug&template=bug_report.md) or in the [Kotlin Slack community](https://slack.kotl.in/).
8+
9+
</ExperimentalFeature>
710

811
Historically, WebSockets have been one of the most complex and error-prone parts of Apollo Kotlin because:
912

@@ -25,7 +28,7 @@ The `com.apollographql.apollo3.network.websocket` implementation provides the fo
2528

2629
While they are `@ApolloExperimental`, we believe the new `.websocket` APIS to be more robust than the non-experimental `.ws` ones. They are safe to use in non-lib use cases.
2730

28-
The "experimental" tag is to account for required API breaking changes based on community feedback. Ideally no change is needed.
31+
The "experimental" tag is to account for required API breaking changes based on community feedback. Ideally no change will be needed.
2932

3033
After a feedback phase, the current `.ws` APIs will become deprecated and the `.websocket` one promoted to stable by removing the `@ApolloExperimental` annotations.
3134

@@ -117,10 +120,10 @@ val apolloClient = ApolloClient.Builder()
117120
.serverUrl(url)
118121
.build()
119122
)
120-
.addRetryOnErrorInterceptor { apolloRequest, exception, attempt ->
123+
.addRetryOnErrorInterceptor { exception, attempt ->
121124
// retry logic here
122125

123126
// return true to retry or false to terminate the Flow
124127
true
125128
}
126-
```
129+
```

docs/source/advanced/http-engine.mdx

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,39 @@ title: Using a custom HTTP client
44

55
By default, Apollo Kotlin uses the following HTTP clients for different platforms/languages:
66

7-
| Platform | HTTP Client |
8-
|----------|-------------|
9-
| Android | [OkHttp](https://square.github.io/okhttp/) |
10-
| JavaScript | [Ktor](https://ktor.io/) |
11-
| iOS/MacOS | [NSURLSesssion](https://developer.apple.com/documentation/foundation/nsurlsession) |
7+
| Platform | HTTP Client |
8+
|-----------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
9+
| Android/JVM | [OkHttp](https://square.github.io/okhttp/) |
10+
| JavaScript/Wasm | [fetch()](https://developer.mozilla.org/en-US/docs/Web/API/fetch) / [Node Fetch](https://www.npmjs.com/package/node-fetch) for HTTP, [Ktor](https://ktor.io/) for WebSockets |
11+
| iOS/MacOS | [NSURLSesssion](https://developer.apple.com/documentation/foundation/nsurlsession) |
1212

13-
You can use a different HTTP client with Apollo Kotlin by creating a custom class that implements the `HttpEngine` interface.
1413

15-
## The `HttpEngine` interface
14+
## Ktor engine
15+
16+
Additionally, an optional implementation based on [Ktor](https://ktor.io/) for all targets is available in the `apollo-engine-ktor` module. To use it, add the following dependency to your project:
17+
18+
```kotlin title="build.gradle[.kts]"
19+
dependencies {
20+
// ...
21+
implementation("com.apollographql.apollo3:apollo-engine-ktor:4.0.0-beta.7")
22+
}
23+
```
24+
25+
And configure your `ApolloClient` to use the Ktor engine:
26+
27+
```kotlin
28+
val client = ApolloClient.Builder()
29+
.serverUrl("https://example.com/graphql")
30+
// Create a new Ktor engine
31+
.httpEngine(KtorHttpEngine())
32+
// Or, if you want to reuse an existing Ktor client
33+
.ktorClient(myKtorClient)
34+
.build()
35+
```
36+
37+
## Implement your own HTTP engine
38+
39+
You can use a different HTTP client with Apollo Kotlin by creating a custom class that implements the `HttpEngine` interface.
1640

1741
The [HttpEngine interface](https://apollographql.github.io/apollo-kotlin/kdoc/apollo-runtime/com.apollographql.apollo3.network.http/-http-engine/index.html)
1842
defines two functions: `execute` and `close`. Here's an example implementation that also includes a couple of helper
@@ -63,14 +87,14 @@ class MyHttpEngine(val wrappedClient: MyClient) : HttpEngine {
6387

6488
This example uses an asynchronous `wrappedClient` that runs the network request in a separate thread. Note that because `HttpEngine.execute` itself is called from a background thread, you can safely block in `execute()`.
6589

66-
## Using your `HttpEngine`
90+
### Using your `HttpEngine`
6791

6892
After you create your `HttpEngine` implementation, you can register it with your [`ApolloClient`](https://apollographql.github.io/apollo-kotlin/kdoc/apollo-runtime/com.apollographql.apollo3/-apollo-client/index.html) instance using [`ApolloClient.Builder.httpEngine`](https://apollographql.github.io/apollo-kotlin/kdoc/apollo-runtime/com.apollographql.apollo3/-apollo-client/-builder/http-engine.html):
6993

7094
```kotlin
7195
// Use your HttpEngine
7296
val client = ApolloClient.Builder()
73-
.serverUrl(serverUrl = "https://com.example/graphql")
97+
.serverUrl(serverUrl = "https://example.com/graphql")
7498
.httpEngine(httpEngine = MyHttpEngine(wrappedClient))
7599
.build()
76100
```

docs/source/advanced/java.mdx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
---
2-
title: Using with Java
2+
title: Using Java
33
---
44

55
This article describes how to use Apollo Kotlin in Java projects.
66

77
## Use the Java codegen
88

9-
Apollo Kotlin generates Kotlin code by default, but you can configure it to use the Java codegen instead:
9+
Apollo Kotlin generates Kotlin code by default, but you can configure it to generate Java code instead:
1010

1111
```kotlin title="build.gradle[.kts]"
1212
apollo {
@@ -39,7 +39,7 @@ import com.apollographql.apollo3.runtime.java.ApolloClient;
3939

4040
// Create and configure an ApolloClient
4141
ApolloClient client = ApolloClient.Builder builder = new ApolloClient.Builder()
42-
.serverUrl("http://localhost:4000/graphql")
42+
.serverUrl("https://example.com/graphql")
4343
.build();
4444

4545
// Call enqueue() to execute a query asynchronously
@@ -79,7 +79,7 @@ When executing subscriptions with the Java runtime, the callback passed to `enqu
7979

8080
```java
8181
ApolloClient apolloClient = new ApolloClient.Builder()
82-
.serverUrl("http://localhost:4000/graphql")
82+
.serverUrl("https://example.com/graphql")
8383
// Configure a protocol factory
8484
.wsProtocolFactory(new ApolloWsProtocol.Factory())
8585
.build();

docs/source/advanced/js-interop.mdx

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ To work around this, Apollo Kotlin provides two alternative solutions to work wi
2020
the [@JsExport](https://kotlinlang.org/docs/js-to-kotlin-interop.html#jsexport-annotation) annotation so that the
2121
dynamic JS object is callable from Kotlin directly.
2222

23-
> ℹ️ `JsExport` is an experimental feature in Kotlin and Apollo Kotlin and may change in future versions.
23+
<ExperimentalFeature>
24+
25+
**`JsExport` is currently [experimental](https://www.apollographql.com/docs/resources/release-stages/#experimental-features) in Apollo Kotlin.** If you have feedback on it, please let us know via [GitHub issues](https://github.com/apollographql/apollo-kotlin/issues/new?assignees=&labels=Type%3A+Bug&template=bug_report.md) or in the [Kotlin Slack community](https://slack.kotl.in/).
26+
27+
</ExperimentalFeature>
2428

2529
Because it bypasses the Kotlin type system, using `jsExport` comes with limitations.
2630
See [Limitations](#Limitations) for more details.
@@ -50,8 +54,7 @@ expect suspend fun <D : Operation.Data> JsonHttpClient.executeApolloOperation(
5054
): D?
5155
```
5256

53-
For non-JS implementations, implement `executeApolloOperation` using your favorite HTTP client (
54-
see [no-runtime](no-runtime)) and `parseJsonResponse`:
57+
For non-JS implementations, implement `executeApolloOperation` using your favorite HTTP client (see [Using the models without apollo-runtime](no-runtime)) and `parseJsonResponse`:
5558

5659
```kotlin
5760
// non-js implementation
@@ -68,8 +71,7 @@ actual suspend fun <D : Operation.Data> JsonHttpClient.executeApolloOperation(
6871
}
6972
```
7073

71-
On JS, you can use `fetch` and `unsafeCast()` to cast the returned javascript object into the @JsExport responseBased
72-
model:
74+
On JS, you can use `fetch` and `unsafeCast()` to cast the returned javascript object into the `@JsExport` responseBased model:
7375

7476
```kotlin
7577
// js implementation
@@ -91,8 +93,7 @@ actual suspend fun <D : Operation.Data> JsonHttpClient.executeApolloOperation(
9193
}
9294
```
9395

94-
For a more complete example see [this gist](https://gist.github.com/baconz/778e8a0b359267292d6e05ad81c19b90) which uses
95-
ktor for non-JS clients.
96+
For a more complete example see [this gist](https://gist.github.com/baconz/778e8a0b359267292d6e05ad81c19b90) which uses Ktor for non-JS clients.
9697

9798
### How it works
9899

@@ -147,9 +148,8 @@ class Point {
147148
```
148149

149150
To work around this, you need to tell the compiler not to mangle property names, which you can do by annotating the
150-
class
151-
with `JsExport`. When you set the `jsExport` option on your service, you tell Apollo to annotate each generated
152-
class with `JsExport` so that the property names are not mangled, and you can safely cast.
151+
class with `@JsExport`. When you set the `jsExport` option on your service, you tell Apollo to annotate each generated
152+
class with `@JsExport` so that the property names are not mangled, and you can safely cast.
153153

154154
### Accessors and Polymorphism
155155

@@ -188,14 +188,14 @@ when (animal.__typename) {
188188

189189
### Limitations
190190

191-
* `JsExport` is an experimental feature in Kotlin and Apollo Kotlin and may change in future versions.
192-
* `JsExport` only makes sense on response based codegen since it requires the Kotlin models to have the same shape as
191+
* `@JsExport` is an experimental feature in Kotlin and Apollo Kotlin and may change in future versions.
192+
* `@JsExport` only makes sense on response based codegen since it requires the Kotlin models to have the same shape as
193193
the JSON.
194194
* On JS, is is not possible to check if a `@JsExport` instance implements a given class. If you need polymorphism, you
195195
must check `__typename` to determine what interface to use.
196196
* Extension functions on generated code break when you use this technique since we are casting a raw JS object and not
197197
actually instantiating a class.
198-
* `generateAsInternal = true` does not work with `JsExport`, since the compiler ends up giving the internal modifier
198+
* `generateAsInternal = true` does not work with `@JsExport`, since the compiler ends up giving the internal modifier
199199
precedence, and thus mangling the property names.
200200
* Custom adapters can only be used when their target types are supported by JS (see the full list
201201
of [supported types](https://kotlinlang.org/docs/js-to-kotlin-interop.html#kotlin-types-in-javascript)).
@@ -205,14 +205,14 @@ when (animal.__typename) {
205205
## `DynamicJsJsonReader`
206206

207207
If you would prefer to use `operationBased` models, and performance is not _as_ critical, you can
208-
use `DynamicJsJsonReader`. `DynamicJsJsonReader` works with a javascript object that is already parsed on the JS side.
208+
use `DynamicJsJsonReader`. `DynamicJsJsonReader` works with a JavaScript object that is already parsed on the JS side.
209209

210-
In JS reading response byte by byte from a byte array like okio is doing incurs a lot of overhead because Kotlin
210+
In JS reading response byte by byte from a byte array like Okio does incurs a lot of overhead because Kotlin
211211
uses `Long` indices in its Arrays, and Longs do not have a JS implementation.
212212

213213
By bypassing this reading, `DynamicJsJsonReader` allows faster reading of responses while still keeping the full Kotlin type information.
214214

215-
In testing we've seen a ~25x performance boost on JS platforms using this parser vs ~100x with the `JsExport` approach.
215+
In testing we've seen a ~25x performance boost on JS platforms using this parser vs ~100x with the `@JsExport` approach.
216216

217217
To use `DynamicJsJsonReader`, your JS implementation above would become:
218218

0 commit comments

Comments
 (0)