Skip to content

Commit 56f3731

Browse files
dariuszkucsmyrick
authored andcommitted
[docs] information about execution and how to return partial data (#542)
* [docs] information about execution and how to return partial data * review comments
1 parent 997c392 commit 56f3731

File tree

8 files changed

+124
-34
lines changed

8 files changed

+124
-34
lines changed

docs/execution/contextual-data.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ build context per query execution through
1515
[GraphQLContextFactory](https://github.com/ExpediaGroup/graphql-kotlin/blob/master/graphql-kotlin-spring-server/src/main/kotlin/com/expediagroup/graphql/spring/execution/GraphQLContextFactory.kt).
1616
Once context factory bean is available in the Spring application context it will then be used in a corresponding
1717
[ContextWebFilter](https://github.com/ExpediaGroup/graphql-kotlin/blob/master/graphql-kotlin-spring-server/src/main/kotlin/com/expediagroup/graphql/spring/execution/ContextWebFilter.kt)
18-
to populate GraphQL context based on the incoming request and make it available during query execution.
18+
to populate GraphQL context based on the incoming request and make it available during query execution. See [graphql-kotlin-spring-server documentation](../spring-server/spring-graphql-context)
19+
for additional details
1920

2021
Once your application is configured to build your custom `MyGraphQLContext`, simply add `@GraphQLContext` annotation to
2122
any function argument and the corresponding GraphQL context from the environment will be automatically injected during
Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,31 @@
1-
---
2-
id: data-fetching-environment
3-
title: Data Fetching Environment
4-
---
5-
Each resolver has a `DataFetchingEnvironment` that can be accessed from graphql-java:
6-
https://www.graphql-java.com/documentation/v13/data-fetching/
7-
8-
You can access this info by including the `DataFetchingEnvironment` as one of the arguments to a Kotlin function. This
9-
argument will not be included in the schema.
10-
11-
```kotlin
12-
class Query {
13-
fun printEnvironmentInfo(environment: DataFetchingEnvironment, value: Int): String {
14-
// Access env data
15-
}
16-
}
17-
```
18-
19-
This will produce the following schema
20-
21-
```graphql
22-
type Query {
23-
printEnvironmentInfo(value: Int!): String!
24-
}
25-
```
26-
27-
You can also use this to retrieve arguments and query information from higher up the query chain. You can see a working
28-
example in the `graphql-kotlin-spring-example` module
29-
[link](https://github.com/ExpediaGroup/graphql-kotlin/blob/master/examples/spring/src/main/kotlin/com/expediagroup/graphql/examples/query/EnvironmentQuery.kt)].
1+
---
2+
id: data-fetching-environment
3+
title: Data Fetching Environment
4+
---
5+
Each resolver has access to a `DataFetchingEnvironment` that provides additional information about the currently executed query including information about what data is requested
6+
as well as details about current execution state. For more details on the `DataFetchingEnvironment` please refer to [graphql-java documentation](https://www.graphql-java.com/documentation/v13/data-fetching/)
7+
8+
You can access this info by including the `DataFetchingEnvironment` as one of the arguments to a Kotlin function. This argument will be automatically populated and injected
9+
during the query execution but will not be included in the schema definition.
10+
11+
```kotlin
12+
class Query {
13+
fun printEnvironmentInfo(environment: DataFetchingEnvironment): String {
14+
// access env data
15+
}
16+
}
17+
```
18+
19+
This will produce the following schema
20+
21+
```graphql
22+
type Query {
23+
printEnvironmentInfo: String!
24+
}
25+
```
26+
27+
You can also use this to retrieve arguments and query information from higher up the query chain. You can see a working
28+
example in the `graphql-kotlin-spring-example` module
29+
[[link](https://github.com/ExpediaGroup/graphql-kotlin/blob/master/examples/spring/src/main/kotlin/com/expediagroup/graphql/examples/query/EnvironmentQuery.kt)].
30+
31+

docs/execution/exceptions.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
id: exceptions
3+
title: Exceptions and Partial Data
4+
---
5+
6+
Exceptions thrown during execution of a query will result in a GraphQLError that is added to a list of errors of the result. See
7+
[graphql-java documentation](https://www.graphql-java.com/documentation/v13/execution/) for more details on how to customize your exception handling.
8+
9+
### Partial Data
10+
11+
GraphQL allows you to return both data and errors in a single response. Depending on the criticality of the encountered error you may want to return
12+
partial data together with the corresponding errors. In Kotlin, functions return only a single value, which means that in order to return both data
13+
and errors you have to explicitly return them wrapped in a `DataFetcherResult` object.
14+
15+
```kotlin
16+
class DataAndErrorsQuery {
17+
fun returnDataAndErrors(): DataFetcherResult<String> {
18+
// some logic here to populate data and capture error
19+
return DataFetcherResult.newResult<String>()
20+
.data(myData)
21+
.error(myError)
22+
.build()
23+
}
24+
}
25+
```
26+
27+
An example of a query returning partial data is available in our [spring example app](https://github.com/ExpediaGroup/graphql-kotlin/blob/master/examples/spring/src/main/kotlin/com/expediagroup/graphql/examples/query/DataAndErrorsQuery.kt).

docs/execution/fetching-data.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
---
2+
id: fetching-data
3+
title: Fetching Data
4+
---
5+
6+
Each field exposed through a GraphQL query has a corresponding resolver (aka data fetcher) associated with it. `graphql-kotlin-schema-generator` generates GraphQL schema
7+
directly from the source code automatically mapping all the fields either to use
8+
[FunctionDataFetcher](https://github.com/ExpediaGroup/graphql-kotlin/blob/master/graphql-kotlin-schema-generator/src/main/kotlin/com/expediagroup/graphql/execution/FunctionDataFetcher.kt)
9+
to resolve underlying functions or a [PropertyDataFetcher](https://www.graphql-java.com/documentation/v13/data-fetching/) to read a value from an underlying Kotlin property.
10+
11+
While all the fields in a GraphQL query are resolved independently to produce a final result, whether field is backed by a function or a property can have significant
12+
performance repercussions. For example, given the following schema:
13+
14+
```graphql
15+
type Query {
16+
product(id: Int!): Product
17+
}
18+
19+
type Product {
20+
id: Int!
21+
name: String!
22+
reviews: [Review!]!
23+
}
24+
25+
type Review {
26+
id: Int!
27+
text: String!
28+
}
29+
```
30+
31+
We can define `Product` as
32+
33+
```kotlin
34+
data class Product(val id: Int, val name: String, reviews: List<Review>)
35+
```
36+
37+
or
38+
39+
```kotlin
40+
class Product(val id: Int, val name: String) {
41+
suspend fun reviews(): List<Reviews> {
42+
// logic to fetch reviews here
43+
}
44+
}
45+
```
46+
47+
If we expose the `reviews` field as a property it will always be populated regardless whether or not your client actually asks for it. On the other hand if `reviews` is backed
48+
by a function, it will only be called if your client asks for this data. In order to minimize the over-fetching of data from your underlying data sources we recommend to
49+
expose all your GraphQL fields that require some additional computations through functions.
50+
51+
### Customizing Default Behavior
52+
53+
You can provide your own custom data fetchers to resolve functions and properties by providing an instance of
54+
[KotlinDataFetcherFactoryProvider](https://github.com/ExpediaGroup/graphql-kotlin/blob/master/graphql-kotlin-schema-generator/src/main/kotlin/com/expediagroup/graphql/execution/KotlinDataFetcherFactoryProvider.kt#L31)
55+
to your [SchemaGeneratorConfig](https://github.com/ExpediaGroup/graphql-kotlin/blob/master/graphql-kotlin-schema-generator/src/main/kotlin/com/expediagroup/graphql/SchemaGeneratorConfig.kt).
56+
See our [spring example app](https://github.com/ExpediaGroup/graphql-kotlin/tree/master/examples/spring) for an example of `CustomDataFetcherFactoryProvider`.

docs/execution/subscriptions.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,6 @@ validation of subscriptions the same as queries and mutations.
3434

3535
### Server Implementation
3636

37-
The server that runs your GraphQL schema will have to support some method for subscriptions, like WebSockets. `graphql-kotlin-spring-server` provides default WebSocket based implementation. See more details in the [server documentation](../server/subscriptions)
37+
The server that runs your GraphQL schema will have to support some method for subscriptions, like WebSockets.
38+
`graphql-kotlin-spring-server` provides a default WebSocket based implementation. See more details in the
39+
[server documentation](../spring-server/subscriptions).

docs/writing-schemas/scalars.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ extended scalar types provided by `graphql-java`.
2727
GraphQL supports a the scalar type ID, a unique identifier that is not intended to be human readable. ID's are
2828
serialized as a String. To mark given field as an ID field you have to annotate it with `@GraphQLID` annotation.
2929

30-
> NOTE: `graphql-java` supports other types (`String`, `Int`, `Long`, or `UUID`) but [due to serialization issues](https://github.com/ExpediaGroup/graphql-kotlin/issues/317) we can only directly support Strings. You can still use a type like UUID internally just as long as you convert or parse the value yourself and handle the errors.
30+
> NOTE: `graphql-java` supports additional types (`String`, `Int`, `Long`, or `UUID`) but [due to serialization issues](https://github.com/ExpediaGroup/graphql-kotlin/issues/317) we can only directly support Strings. You can still use a type like UUID internally just as long as you convert or parse the value yourself and handle the errors.
3131
3232
```kotlin
3333
data class Person(

examples/spring/src/main/kotlin/com/expediagroup/graphql/examples/query/DataAndErrors.kt renamed to examples/spring/src/main/kotlin/com/expediagroup/graphql/examples/query/DataAndErrorsQuery.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import org.springframework.stereotype.Component
2525
import java.util.concurrent.CompletableFuture
2626

2727
@Component
28-
class DataAndErrors : Query {
28+
class DataAndErrorsQuery : Query {
2929

3030
fun returnDataAndErrors(): DataFetcherResult<String> {
3131
val error = SimpleKotlinGraphQLError(RuntimeException(), listOf(SourceLocation(1, 1)), ExecutionPath.rootPath().toList())

website/sidebars.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,11 @@
3737
"type": "subcategory",
3838
"label": "Execution",
3939
"ids": [
40+
"execution/fetching-data",
41+
"execution/async-models",
42+
"execution/exceptions",
4043
"execution/data-fetching-environment",
4144
"execution/contextual-data",
42-
"execution/async-models",
4345
"execution/subscriptions"
4446
]
4547
}

0 commit comments

Comments
 (0)