Skip to content

Commit 8f2f343

Browse files
martinbonninbenjie
andauthored
Add @onError as a possible solution to semantic nullability (#1652)
Co-authored-by: Benjie <[email protected]>
1 parent 1abb4b3 commit 8f2f343

File tree

1 file changed

+52
-24
lines changed

1 file changed

+52
-24
lines changed

rfcs/SemanticNullability.md

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,9 @@ Note: Traditional non-nullable types will effectively become semantically
224224
non-nullable when error propagation is disabled no matter which solution is
225225
chosen, so this criteria is only concerned with traditionally nullable types.
226226

227-
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] |
228-
| --------------- | --------------- | --------------- | --------------- |
229-
|||||
227+
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
228+
|-----------------|-----------------|-----------------|-----------------|-----------------|
229+
| | | | | 🚫👍 |
230230

231231
Criteria score: 🥇
232232

@@ -236,9 +236,9 @@ Users should be able to adopt semantic nullability into an existing schema, and
236236
when doing so all existing operations should remain valid, and should have the
237237
same meaning as they always did.
238238

239-
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] |
240-
| --------------- | --------------- | --------------- | --------------- |
241-
|| 🚫 |||
239+
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
240+
|-----------------|-----------------|-----------------|-----------------|-----------------|
241+
| | 🚫 | | | |
242242

243243
Criteria score: 🥇
244244

@@ -248,9 +248,9 @@ GraphQL has been public for 10 years and there's a lot of content out there
248248
noting that GraphQL types are nullable by default (unadorned type is nullable)
249249
and that `!` means non-nullable. Our changes should not invalidate this content.
250250

251-
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] |
252-
| --------------- | --------------- | --------------- | --------------- |
253-
|| 🚫 || 🚫 |
251+
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
252+
|-----------------|-----------------|-----------------|-----------------|-----------------|
253+
| | 🚫 | | 🚫 | |
254254

255255
Criteria score: 🥈
256256

@@ -260,9 +260,9 @@ The GraphQL languages similarity to JSON is one of its strengths, making it
260260
immediately feel familiar. Syntax used should feel obvious to developers new to
261261
GraphQL.
262262

263-
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] |
264-
| --------------- | --------------- | --------------- | --------------- |
265-
| 🚫 ||||
263+
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
264+
|-----------------|-----------------|-----------------|-----------------|-----------------|
265+
| 🚫 | | | | ⚠️ |
266266

267267
Criteria score: 🥈
268268

@@ -272,9 +272,9 @@ When a user wishes to replace the value for an input field or argument with a
272272
variable in their GraphQL operation, the type syntax should be either identical
273273
or similar, and should carry the same meaning.
274274

275-
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] |
276-
| --------------- | --------------- | --------------- | --------------- |
277-
|||| 🚫 |
275+
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
276+
|-----------------|-----------------|-----------------|-----------------|-----------------|
277+
| | | | 🚫 | |
278278

279279
Criteria score: 🥇
280280

@@ -283,9 +283,9 @@ Criteria score: 🥇
283283
Where a proposal allows alternative syntaxes to be used, the two syntaxes should
284284
not cause confusion.
285285

286-
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] |
287-
| --------------- | --------------- | --------------- | --------------- |
288-
|||| 🚫 |
286+
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
287+
|-----------------|-----------------|-----------------|-----------------|-----------------|
288+
| | | | 🚫 | |
289289

290290
Criteria score: 🥇
291291

@@ -297,12 +297,15 @@ still keep errors local to the same positions that they did when they were
297297
published), allowing for the "partial success" feature of GraphQL to continue to
298298
shine and not compromising the resiliency of legacy deployed app versions.
299299

300-
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] |
301-
| --------------- | --------------- | --------------- | --------------- |
302-
|||||
300+
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
301+
| --------------- | --------------- | --------------- | --------------- |-----------------|
302+
||||| 🚫 |
303303

304304
Criteria score: 🥇
305305

306+
* ✂️ Objection: proposal to lower the score to 🥈. With enough advance notice and a clear upgrade
307+
path for legacy apps, the tradeoff might be acceptable.
308+
306309
<!--
307310
308311
Template for new items:
@@ -311,9 +314,9 @@ Template for new items:
311314
312315
DESCRIPTION
313316
314-
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] |
315-
| --------------- | --------------- | --------------- | --------------- |
316-
| | ❔ | ❔ | ❔ |
317+
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
318+
| --------------- | --------------- | --------------- | --------------- |-----------------|
319+
| ? | ? | ? | ? | ? |
317320
318321
Criteria score: ❔
319322
@@ -523,3 +526,28 @@ directive is present, and a `?` symbol is used to indicate a nullable position.
523526
unexpected and will likely lead to confusion.
524527
- [G][criteria-g]
525528
- ✅ Error capture positions unchanged when error propagation enabled
529+
530+
## 💡 5. Use non-null in semantically non-nullable places and encourage disabling error propagation
531+
532+
**Champion**: @martinbonnin
533+
534+
- Discussion: https://github.com/graphql/nullability-wg/discussions/85
535+
536+
This proposal relies on the ability of clients to opt out of error propagation; instead of introducing a new type it instructs schema authors to optimize for error-handling clients and use the traditional non-null type (`!`) on all semantically non-null fields.
537+
538+
### ⚖️ Evaluation
539+
540+
- [A][criteria-a]
541+
- 🚫👍 The nullability used in both error-propagation and no-error-propagation modes are the same. This is a feature, not a bug!
542+
- [B][criteria-b]
543+
- ✅ The change from nullable to non-nullable on output is backwards compatible from a type perspective; for impact on error boundaries see G.
544+
- [C][criteria-c]
545+
- ✅ `Int` means nullable, and `Int!` means non-nullable, still.
546+
- [D][criteria-d]
547+
- ⚠️ Adding `@onError` to operations is not immediately intuitive but most error-handling clients should add it automatically, making it transparent to end users.
548+
- [E][criteria-e]
549+
- ✅ Same syntax.
550+
- [F][criteria-f]
551+
- ✅ Same syntax.
552+
- [G][criteria-g]
553+
- 🚫 Using non-null in more positions will change the error boundary positions when error propagation is enabled.

0 commit comments

Comments
 (0)