From 9aa8b0348afb535e470664b6f2bac5eeba41c153 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Sat, 25 Nov 2023 22:22:18 +0100 Subject: [PATCH 01/12] Add nullability directives --- __index__.md | 5 ++- index.md | 4 ++ nullability/v0.1/nullability-v0.1.graphql | 55 +++++++++++++++++++++++ nullability/v0.1/nullability-v0.1.md | 23 ++++++++++ 4 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 nullability/v0.1/nullability-v0.1.graphql create mode 100644 nullability/v0.1/nullability-v0.1.md diff --git a/__index__.md b/__index__.md index d0e4780..f01e54c 100644 --- a/__index__.md +++ b/__index__.md @@ -11,8 +11,9 @@ - **[join/v0.1](/join/v0.1)** ([📄 graphql](join/v0.1/join-v0.1.graphql)) - **[join/v0.2](/join/v0.2)** ([📄 graphql](join/v0.2/join-v0.2.graphql)) - **[join/v0.3](/join/v0.3)** ([📄 graphql](join/v0.3/join-v0.3.graphql)) +- **[kotlin_labs/v0.1](/kotlin_labs/v0.1)** ([📄 graphql](kotlin_labs/v0.1/kotlin_labs-v0.1.graphql)) +- **[kotlin_labs/v0.2](/kotlin_labs/v0.2)** ([📄 graphql](kotlin_labs/v0.2/kotlin_labs-v0.2.graphql)) - **[link/v1.0](/link/v1.0)** ([📄 graphql](link/v1.0/link-v1.0.graphql)) +- **[nullability/v0.1](/nullability/v0.1)** ([📄 graphql](nullability/v0.1/nullability-v0.1.graphql)) - **[tag/v0.1](/tag/v0.1)** ([📄 graphql](tag/v0.1/tag-v0.1.graphql)) - **[tag/v0.2](/tag/v0.2)** ([📄 graphql](tag/v0.2/tag-v0.2.graphql)) -- **[kotlin_labs/v0.1](/kotlin_labs/v0.1)** ([📄 graphql](kotlin_labs/v0.1/kotlin_labs-v0.1.graphql)) -- **[kotlin_labs/v0.2](/kotlin_labs/v0.2)** ([📄 graphql](kotlin_labs/v0.2/kotlin_labs-v0.2.graphql)) diff --git a/index.md b/index.md index ae93303..f9bccaf 100644 --- a/index.md +++ b/index.md @@ -39,6 +39,10 @@ [kotlin_labs v0.2](kotlin_labs/v0.2) incubating directives supported by the Apollo Kotlin client +## nullability v0.1 + +[nullability v0.1](nullability/v0.1) incubating directives to work with nullability + # All Schemas Everything in this library: diff --git a/nullability/v0.1/nullability-v0.1.graphql b/nullability/v0.1/nullability-v0.1.graphql new file mode 100644 index 0000000..0550232 --- /dev/null +++ b/nullability/v0.1/nullability-v0.1.graphql @@ -0,0 +1,55 @@ +""" +Indicates that a field is only null if there is a matching error in the `errors` array. +In all other cases, the field is non-null. + +Tools doing code generation may use this information to generate the field as non-null. + +This directive can be applied on field definitions: + +```graphql +type User { + email: String @nullOnlyOnError +} +``` + +It can also be applied on object type extensions for use in client applications that do +not own the base schema: + +```graphql +extend type User @nullOnlyOnError(field: "email") +``` + +Control over list items is done using the `level` argument: + +```graphql +type User { + # friends is nullable but friends[0] is null only on errors + friends @nullOnlyOnError(level: 1) +} +``` + +@param field the name of the field if applied to an object definition or null if applied +to a field definition + +@param level in case of a list type, level is the dimension where to apply the modifier, +starting at 0 if there is no list. +If level is null, the modifier is applied to all levels +""" +directive @nullOnlyOnError(field: String = null, level: Int = null) repeatable on FIELD_DEFINITION | OBJECT + +""" +Indicates that a field acts as an error boundary in case of a GraphQL error. + +By default, the first GraphQL error throws and fails the whole response. + +@param level in case of a list type, level is the dimension where to apply the modifier, +starting at 0 if there is no list. +If level is null, the modifier is applied to all levels +""" +directive @catch(if: Boolean! = true, to: CatchTo! = RESULT, level: Int = null) repeatable on FIELD + +enum CatchTo { + NULL, + THROW, + RESULT, +} \ No newline at end of file diff --git a/nullability/v0.1/nullability-v0.1.md b/nullability/v0.1/nullability-v0.1.md new file mode 100644 index 0000000..c586b2e --- /dev/null +++ b/nullability/v0.1/nullability-v0.1.md @@ -0,0 +1,23 @@ +# nullability v0.1 + +

Experimental nullability directives

+ +```raw html + + + +
StatusRelease
Version0.1
+ + +``` + +This specification provides a list of directives to help dealing with nullability. For more information, see [the nullability working group GitHub](https://github.com/graphql/nullability-wg) + + +#! @nullOnlyOnError + +:::[definition](nullability-v0.1.graphql#@nullOnlyOnError) + +#! @catch + +:::[definition](nullability-v0.1.graphql#@catch) From cd8afbd85c303d663a607921d29e22d1bedab912 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Mon, 27 Nov 2023 17:26:42 +0100 Subject: [PATCH 02/12] fixes from https://github.com/apollographql/apollo-kotlin/pull/5405 Thanks @BoD --- nullability/v0.1/nullability-v0.1.graphql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nullability/v0.1/nullability-v0.1.graphql b/nullability/v0.1/nullability-v0.1.graphql index 0550232..3e4d050 100644 --- a/nullability/v0.1/nullability-v0.1.graphql +++ b/nullability/v0.1/nullability-v0.1.graphql @@ -24,7 +24,7 @@ Control over list items is done using the `level` argument: ```graphql type User { # friends is nullable but friends[0] is null only on errors - friends @nullOnlyOnError(level: 1) + friends: [User] @nullOnlyOnError(level: 1) } ``` @@ -46,7 +46,7 @@ By default, the first GraphQL error throws and fails the whole response. starting at 0 if there is no list. If level is null, the modifier is applied to all levels """ -directive @catch(if: Boolean! = true, to: CatchTo! = RESULT, level: Int = null) repeatable on FIELD +directive @catch(if: Boolean! = true, to: CatchTo! = RESULT, level: Int = null) repeatable on FIELD | SCHEMA enum CatchTo { NULL, From 10ae7f80285a701085c2fb0b00b74d5651287f59 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Mon, 27 Nov 2023 19:12:34 +0100 Subject: [PATCH 03/12] remove `if` --- nullability/v0.1/nullability-v0.1.graphql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nullability/v0.1/nullability-v0.1.graphql b/nullability/v0.1/nullability-v0.1.graphql index 3e4d050..fa23fdb 100644 --- a/nullability/v0.1/nullability-v0.1.graphql +++ b/nullability/v0.1/nullability-v0.1.graphql @@ -46,7 +46,7 @@ By default, the first GraphQL error throws and fails the whole response. starting at 0 if there is no list. If level is null, the modifier is applied to all levels """ -directive @catch(if: Boolean! = true, to: CatchTo! = RESULT, level: Int = null) repeatable on FIELD | SCHEMA +directive @catch(to: CatchTo! = RESULT, level: Int = null) repeatable on FIELD enum CatchTo { NULL, From ccbbd765b2c22556913a9e6dd9cff96c9944e058 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Wed, 29 Nov 2023 11:21:13 +0100 Subject: [PATCH 04/12] nullOnlyOnErrors -> semanticNonNull --- nullability/v0.1/nullability-v0.1.graphql | 18 ++++++++++++------ nullability/v0.1/nullability-v0.1.md | 4 ++-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/nullability/v0.1/nullability-v0.1.graphql b/nullability/v0.1/nullability-v0.1.graphql index fa23fdb..c8e0bfb 100644 --- a/nullability/v0.1/nullability-v0.1.graphql +++ b/nullability/v0.1/nullability-v0.1.graphql @@ -8,7 +8,7 @@ This directive can be applied on field definitions: ```graphql type User { - email: String @nullOnlyOnError + email: String @semanticNonNull } ``` @@ -16,7 +16,7 @@ It can also be applied on object type extensions for use in client applications not own the base schema: ```graphql -extend type User @nullOnlyOnError(field: "email") +extend type User @semanticNonNull(field: "email") ``` Control over list items is done using the `level` argument: @@ -24,7 +24,7 @@ Control over list items is done using the `level` argument: ```graphql type User { # friends is nullable but friends[0] is null only on errors - friends: [User] @nullOnlyOnError(level: 1) + friends: [User] @semanticNonNull(level: 1) } ``` @@ -35,7 +35,7 @@ to a field definition starting at 0 if there is no list. If level is null, the modifier is applied to all levels """ -directive @nullOnlyOnError(field: String = null, level: Int = null) repeatable on FIELD_DEFINITION | OBJECT +directive @semanticNonNull(field: String = null, level: Int = null) repeatable on FIELD_DEFINITION | OBJECT """ Indicates that a field acts as an error boundary in case of a GraphQL error. @@ -50,6 +50,12 @@ directive @catch(to: CatchTo! = RESULT, level: Int = null) repeatable on FIELD enum CatchTo { NULL, - THROW, RESULT, -} \ No newline at end of file +} + +""" +Never throw on errors. + +This is used for backward compatibility for clients where this was the default behaviour. +""" +directive @ignoreErrors on QUERY | MUTATION | SUBSCRIPTION \ No newline at end of file diff --git a/nullability/v0.1/nullability-v0.1.md b/nullability/v0.1/nullability-v0.1.md index c586b2e..2927a11 100644 --- a/nullability/v0.1/nullability-v0.1.md +++ b/nullability/v0.1/nullability-v0.1.md @@ -14,9 +14,9 @@ This specification provides a list of directives to help dealing with nullability. For more information, see [the nullability working group GitHub](https://github.com/graphql/nullability-wg) -#! @nullOnlyOnError +#! @semanticNonNull -:::[definition](nullability-v0.1.graphql#@nullOnlyOnError) +:::[definition](nullability-v0.1.graphql#@semanticNonNull) #! @catch From 629fa8431d974895f8b2b0afa3d91f5d65cf6d8a Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Wed, 29 Nov 2023 12:00:02 +0100 Subject: [PATCH 05/12] wording --- nullability/v0.1/nullability-v0.1.graphql | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/nullability/v0.1/nullability-v0.1.graphql b/nullability/v0.1/nullability-v0.1.graphql index c8e0bfb..3f1924e 100644 --- a/nullability/v0.1/nullability-v0.1.graphql +++ b/nullability/v0.1/nullability-v0.1.graphql @@ -28,23 +28,25 @@ type User { } ``` -@param field the name of the field if applied to an object definition or null if applied -to a field definition +The `field` argument is the name of the field if `@semanticNonNull` is applied to an object definition. +If `@semanticNonNull` is applied to a field definition, `field` must be null. -@param level in case of a list type, level is the dimension where to apply the modifier, -starting at 0 if there is no list. -If level is null, the modifier is applied to all levels +The `level` argument can be used to indicate what level is semantically non null in case of lists. +`level` starts at 0 if there is no list. If `level` is null, all levels are semantically non null. """ directive @semanticNonNull(field: String = null, level: Int = null) repeatable on FIELD_DEFINITION | OBJECT """ -Indicates that a field acts as an error boundary in case of a GraphQL error. +Indicates that the given position stops GraphQL errors to propagate up the tree. -By default, the first GraphQL error throws and fails the whole response. +By default, the first GraphQL error stops the parsing and fails the whole response. +Using `@catch` recovers from this error and allows the parsing to continue. -@param level in case of a list type, level is the dimension where to apply the modifier, -starting at 0 if there is no list. -If level is null, the modifier is applied to all levels +The `to` argument can be used to choose how to recover from errors. See `CatchTo` +for more details. + +The `level` argument can be used to indicate where to catch in case of lists. +`level` starts at 0 if there is no list. If `level` is null, all levels catch. """ directive @catch(to: CatchTo! = RESULT, level: Int = null) repeatable on FIELD From 6f3580ee62e20b17250f87f14ccf3c55b12fbe94 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Wed, 29 Nov 2023 12:02:12 +0100 Subject: [PATCH 06/12] add description to CatchTo enum values --- nullability/v0.1/nullability-v0.1.graphql | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/nullability/v0.1/nullability-v0.1.graphql b/nullability/v0.1/nullability-v0.1.graphql index 3f1924e..e9cae9b 100644 --- a/nullability/v0.1/nullability-v0.1.graphql +++ b/nullability/v0.1/nullability-v0.1.graphql @@ -51,8 +51,16 @@ The `level` argument can be used to indicate where to catch in case of lists. directive @catch(to: CatchTo! = RESULT, level: Int = null) repeatable on FIELD enum CatchTo { - NULL, + """ + Map to a result type that can contain either a value or an error. + """ RESULT, + """ + Map to a nullable type that will be null in the case of error. + This does not allow to distinguish between semantic null and error but + can be simpler in some cases. + """ + NULL, } """ From 646a5522d6921d6cc2522ee87f4b79a666e2ec88 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Wed, 6 Dec 2023 11:38:07 +0100 Subject: [PATCH 07/12] Update nullability/v0.1/nullability-v0.1.graphql Co-authored-by: Benoit Lubek --- nullability/v0.1/nullability-v0.1.graphql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nullability/v0.1/nullability-v0.1.graphql b/nullability/v0.1/nullability-v0.1.graphql index e9cae9b..2ad5979 100644 --- a/nullability/v0.1/nullability-v0.1.graphql +++ b/nullability/v0.1/nullability-v0.1.graphql @@ -48,7 +48,7 @@ for more details. The `level` argument can be used to indicate where to catch in case of lists. `level` starts at 0 if there is no list. If `level` is null, all levels catch. """ -directive @catch(to: CatchTo! = RESULT, level: Int = null) repeatable on FIELD +directive @catch(to: CatchTo! = RESULT, level: Int = null) repeatable on FIELD | SCHEMA enum CatchTo { """ From 0c610d2ebfef4b139ac73de266e953f6154cc08e Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Wed, 6 Dec 2023 11:49:20 +0100 Subject: [PATCH 08/12] Add CatchTo.THROW --- nullability/v0.1/nullability-v0.1.graphql | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nullability/v0.1/nullability-v0.1.graphql b/nullability/v0.1/nullability-v0.1.graphql index 2ad5979..2696888 100644 --- a/nullability/v0.1/nullability-v0.1.graphql +++ b/nullability/v0.1/nullability-v0.1.graphql @@ -61,6 +61,10 @@ enum CatchTo { can be simpler in some cases. """ NULL, + """ + Do not catch and let any exception through + """ + THROW } """ @@ -68,4 +72,4 @@ Never throw on errors. This is used for backward compatibility for clients where this was the default behaviour. """ -directive @ignoreErrors on QUERY | MUTATION | SUBSCRIPTION \ No newline at end of file +directive @ignoreErrors on QUERY | MUTATION | SUBSCRIPTION From 9f1795c58efff0cb0d0e5e25e174386930c55f88 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Thu, 30 Nov 2023 00:56:27 +0100 Subject: [PATCH 09/12] add comments --- nullability/v0.1/nullability-v0.1.graphql | 7 ++++++- nullability/v0.1/nullability-v0.1.md | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/nullability/v0.1/nullability-v0.1.graphql b/nullability/v0.1/nullability-v0.1.graphql index 2696888..50d3b8c 100644 --- a/nullability/v0.1/nullability-v0.1.graphql +++ b/nullability/v0.1/nullability-v0.1.graphql @@ -42,6 +42,11 @@ Indicates that the given position stops GraphQL errors to propagate up the tree. By default, the first GraphQL error stops the parsing and fails the whole response. Using `@catch` recovers from this error and allows the parsing to continue. +`@catch` can be used on the schema definition. In this case, it is the default for +every field that can return an error (nullable fields). +If no `@catch` is applied to the schema definition, errors are not +caught by default and the parsing stops at the first error. + The `to` argument can be used to choose how to recover from errors. See `CatchTo` for more details. @@ -68,7 +73,7 @@ enum CatchTo { } """ -Never throw on errors. +Never throw on field errors. This is used for backward compatibility for clients where this was the default behaviour. """ diff --git a/nullability/v0.1/nullability-v0.1.md b/nullability/v0.1/nullability-v0.1.md index 2927a11..01804c1 100644 --- a/nullability/v0.1/nullability-v0.1.md +++ b/nullability/v0.1/nullability-v0.1.md @@ -21,3 +21,7 @@ This specification provides a list of directives to help dealing with nullabilit #! @catch :::[definition](nullability-v0.1.graphql#@catch) + +#! @ignoreFieldErrors + +:::[definition](nullability-v0.1.graphql#@ignoreFieldErrors) \ No newline at end of file From 7a1b2347131e9ea19e0098191136152ac609dc54 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Mon, 11 Dec 2023 16:31:45 +0100 Subject: [PATCH 10/12] Update nullability/v0.1/nullability-v0.1.md Co-authored-by: Benoit Lubek --- nullability/v0.1/nullability-v0.1.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nullability/v0.1/nullability-v0.1.md b/nullability/v0.1/nullability-v0.1.md index 01804c1..8b003ad 100644 --- a/nullability/v0.1/nullability-v0.1.md +++ b/nullability/v0.1/nullability-v0.1.md @@ -22,6 +22,6 @@ This specification provides a list of directives to help dealing with nullabilit :::[definition](nullability-v0.1.graphql#@catch) -#! @ignoreFieldErrors +#! @ignoreErrors -:::[definition](nullability-v0.1.graphql#@ignoreFieldErrors) \ No newline at end of file +:::[definition](nullability-v0.1.graphql#@ignoreErrors) \ No newline at end of file From 2393992207c4cbea8b585c8b78fe7c7e77613702 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Mon, 11 Dec 2023 16:35:38 +0100 Subject: [PATCH 11/12] only keep the latest version in the table of contents --- index.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/index.md b/index.md index f9bccaf..beae8b2 100644 --- a/index.md +++ b/index.md @@ -31,10 +31,6 @@ [inaccessible v0.2](inaccessible/v0.2) masks fields and types from a graph's public API -## kotlin_labs v0.1 - -[kotlin_labs v0.1](kotlin_labs/v0.1) incubating directives supported by the Apollo Kotlin client - ## kotlin_labs v0.2 [kotlin_labs v0.2](kotlin_labs/v0.2) incubating directives supported by the Apollo Kotlin client From 639ab1f1df9f39dfdeb338d9cd7363c4f87a3021 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Mon, 11 Dec 2023 16:42:33 +0100 Subject: [PATCH 12/12] wording --- nullability/v0.1/nullability-v0.1.graphql | 27 ++++++++++------------- nullability/v0.1/nullability-v0.1.md | 2 +- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/nullability/v0.1/nullability-v0.1.graphql b/nullability/v0.1/nullability-v0.1.graphql index 50d3b8c..c84deea 100644 --- a/nullability/v0.1/nullability-v0.1.graphql +++ b/nullability/v0.1/nullability-v0.1.graphql @@ -37,37 +37,34 @@ The `level` argument can be used to indicate what level is semantically non null directive @semanticNonNull(field: String = null, level: Int = null) repeatable on FIELD_DEFINITION | OBJECT """ -Indicates that the given position stops GraphQL errors to propagate up the tree. +Indicates how clients should handle errors on a given position. -By default, the first GraphQL error stops the parsing and fails the whole response. -Using `@catch` recovers from this error and allows the parsing to continue. - -`@catch` can be used on the schema definition. In this case, it is the default for -every field that can return an error (nullable fields). -If no `@catch` is applied to the schema definition, errors are not -caught by default and the parsing stops at the first error. - -The `to` argument can be used to choose how to recover from errors. See `CatchTo` -for more details. +When used on the schema definition, `@catch` applies to every position that can return an error. The `level` argument can be used to indicate where to catch in case of lists. `level` starts at 0 if there is no list. If `level` is null, all levels catch. + +See `CatchTo` for more details. """ directive @catch(to: CatchTo! = RESULT, level: Int = null) repeatable on FIELD | SCHEMA enum CatchTo { """ - Map to a result type that can contain either a value or an error. + Catch the error and map the position to a result type that can contain either + a value or an error. """ RESULT, """ - Map to a nullable type that will be null in the case of error. - This does not allow to distinguish between semantic null and error but + Catch the error and map the position to a nullable type that will be null + in the case of error. + This does not allow to distinguish between semantic null and error null but can be simpler in some cases. """ NULL, """ - Do not catch and let any exception through + Throw the error. + Parent fields can recover using `RESULT` or `NULL`. + If no parent field recovers, the parsing stops. """ THROW } diff --git a/nullability/v0.1/nullability-v0.1.md b/nullability/v0.1/nullability-v0.1.md index 8b003ad..095ed82 100644 --- a/nullability/v0.1/nullability-v0.1.md +++ b/nullability/v0.1/nullability-v0.1.md @@ -11,7 +11,7 @@ ``` -This specification provides a list of directives to help dealing with nullability. For more information, see [the nullability working group GitHub](https://github.com/graphql/nullability-wg) +This specification provides a list of directives to help dealing with nullability. For more information, see [the nullability working group GitHub repository.](https://github.com/graphql/nullability-wg) #! @semanticNonNull