Skip to content

Commit 93aa905

Browse files
authored
Add more criteria to comparison (#1664)
1 parent d347779 commit 93aa905

File tree

1 file changed

+229
-0
lines changed

1 file changed

+229
-0
lines changed

β€Žrfcs/SemanticNullability.md

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,145 @@ The implementation required to make the proposal work should be simple.
316316

317317
Criteria score: πŸ₯ˆ
318318

319+
## 🎯 I. Syntax used in executable documents should be unchanged
320+
321+
Executable documents do not differentiate between semantic and strict non-null
322+
since inputs never handle "errors" ("null only on error" is the same as "not
323+
null" on input). As such, there's no benefit to clients for the syntax of
324+
executable documents to change.
325+
326+
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
327+
|-----------------|-----------------|-----------------|-----------------|-----------------|
328+
| βœ… | ❔ | βœ… | 🚫 | βœ… |
329+
330+
Criteria score: πŸ₯‡
331+
332+
## 🎯 J. Type reasoning should remain local
333+
334+
The type of a field (`foo: Int`) can be determined by looking at the field and
335+
its type; the reader should not have to read a document or schema directive to
336+
determine how the type should be interpreted.
337+
338+
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
339+
|-----------------|-----------------|-----------------|-----------------|-----------------|
340+
| βœ… | ❔ | ⚠️ | 🚫 | βœ… |
341+
342+
Criteria score: πŸ₯‡
343+
344+
## 🎯 K. Introspection must be backwards compatible
345+
346+
We do not want to break existing tooling.
347+
348+
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
349+
|-----------------|-----------------|-----------------|-----------------|-----------------|
350+
| βœ… | ❔ | βœ… | ❔ | βœ… |
351+
352+
Criteria score: πŸ₯‡
353+
354+
## 🎯 L. General GraphQL consumers should only need to think about nullable vs non-nullable
355+
356+
Schema authors and client frameworks can handle different types of nullability based around
357+
error handling and error propagation, but consumers (frontend developers) should only need
358+
to deal with nullable or non-nullable as presented to them by their client framework of choice.
359+
360+
May contradict: M
361+
362+
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
363+
|-----------------|-----------------|-----------------|-----------------|-----------------|
364+
| βœ… | ❔ | βœ… | ❔ | βœ… |
365+
366+
Criteria score: πŸ₯‡
367+
368+
## 🎯 M. The SDL should have exactly one form used by all producers and consumers
369+
370+
The SDL should not be influenced by client features such as local extensions and
371+
error propagation mechanics, and should always represent the true full source
372+
schema SDL.
373+
374+
May contradict: L
375+
376+
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
377+
|-----------------|-----------------|-----------------|-----------------|-----------------|
378+
| ⚠️ | ❔ | ⚠️ | ❔ | βœ… |
379+
380+
Criteria score: πŸ₯‡
381+
382+
## 🎯 N. The solution should add value even with error propagation enabled
383+
384+
Even when error propagation is enabled, it's valuable to be able to tell the
385+
difference between a field that is truly (semantically) nullable, and one
386+
that's only nullable because errors may occur. GraphQL-TOE can be used in such
387+
situations so that codegen can safely use non-nullable types in semantically
388+
non-nullable positions.
389+
390+
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
391+
|-----------------|-----------------|-----------------|-----------------|-----------------|
392+
| βœ… | βœ… | βœ… | βœ… | 🚫 |
393+
394+
Criteria score: πŸ₯‡
395+
396+
## 🎯 O. Should not have breaking changes for existing executable documents
397+
398+
It should be possible to enable the solution without negatively impacting
399+
existing deployed clients.
400+
401+
Per Lee:
402+
403+
> A breaking change is a client observable change in behavior. The decade old
404+
> GraphQL query should work in the same way as it always has. (We sometimes
405+
> allow inconsequential changes in behavior, but bubbling the error up isn't
406+
> inconsequential.)
407+
408+
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
409+
|-----------------|-----------------|-----------------|-----------------|-----------------|
410+
| βœ… | ❔ | βœ… | βœ… | 🚫 |
411+
412+
413+
Note: though this criteria is currently not considered due to overlap with B
414+
and G, it acts as a reminder to look for other forms of breaking change, and
415+
helps to reason _why_ B and G are important.
416+
417+
Criteria score: X (not considered - covered by B and G)
418+
419+
420+
## 🎯 P. The solution should result in users marking all semantically non-null fields as such
421+
422+
When a field returns data that the business logic dictates does not and will
423+
never return a legitimate (non-error) null, the schema authors should have no
424+
hesitation over marking it as semantically non-nullable - and thus all
425+
semantically non-nullable fields should be marked as such.
426+
427+
Per Benoit:
428+
429+
> Not sure how to express it well, but I feel there should be a criteria to
430+
> mean something like β€œthe solution encourages that eventually most fields in
431+
> most schemas are semantically non null”. As a client developer that’s kind of
432+
> an outcome of this whole effort I’d like to see happening.
433+
434+
435+
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
436+
|-----------------|-----------------|-----------------|-----------------|-----------------|
437+
| βœ… | βœ… | βœ… | βœ… | 🚫 |
438+
439+
Criteria score: πŸ₯‡
440+
441+
## 🎯 Q. Migrating the unadorned output type to other forms of nullability should be non-breaking
442+
443+
The default (unadorned) type should be a type that you can migrate away from,
444+
once nullability expectations become more concrete, without breaking existing
445+
client queries.
446+
447+
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
448+
|-----------------|-----------------|-----------------|-----------------|-----------------|
449+
| βœ… | 🚫 | βœ… | 🚫 | βœ… |
450+
451+
Note: this is not necessarily a duplicate of C as it doesn't specifically
452+
require the unadorned type be nullable, however no proposal currently proposes
453+
a mechanism for moving from any non-nullable type to a nullable type in a
454+
non-breaking way, and thus this criteria is _currently_ discounted.
455+
456+
Criteria score: X (not considered)
457+
319458
<!--
320459
321460
Template for new items:
@@ -400,6 +539,23 @@ have been discussed the choice of symbol comes down mostly to aesthetics.
400539
- βœ… Error capture positions unchanged when error propagation enabled
401540
- [H][criteria-h]
402541
- βœ… Implementation and spec simplicity.
542+
- [I][criteria-i]
543+
- βœ… `*` doesn't apply on input, so syntax is unchanged.
544+
- [J][criteria-j]
545+
- βœ… Local syntax only
546+
- [K][criteria-k]
547+
- βœ… Introspection backwards compatible via `__Field.type(includeSemanticNonNull: Boolean! = false)`
548+
- [L][criteria-l]
549+
- βœ… Proposal encourages consumers to use client-produced SDL which only uses traditional nullability (`Type`/`Type!`)
550+
- [M][criteria-m]
551+
- ⚠️ You can use the same SDL everywhere, but that's not what this solution
552+
encourages.
553+
- [N][criteria-n]
554+
- βœ… Indicates semantically non-null and strictly non-null types separately
555+
- [O][criteria-o]
556+
- βœ… Client syntax unchanged
557+
- [P][criteria-p]
558+
- βœ… There are no drawbacks to adding semantically non-nullable fields
403559

404560
## πŸ’‘ 2. "Strict Semantic Nullability"
405561

@@ -441,6 +597,23 @@ symbol) to indicate that a position may semantically be null.
441597
- βœ… Error capture positions unchanged when error propagation enabled
442598
- [H][criteria-h]
443599
- 🚫 Implementation and spec simplicity.
600+
- [I][criteria-i]
601+
- ❔
602+
- [J][criteria-j]
603+
- ❔
604+
- [K][criteria-k]
605+
- ❔
606+
- [L][criteria-l]
607+
- ❔
608+
- [M][criteria-m]
609+
- ❔
610+
- [N][criteria-n]
611+
- βœ… Indicates semantically non-null and strictly non-null types separately
612+
- [O][criteria-o]
613+
- ❔
614+
- [P][criteria-p]
615+
- ❔
616+
444617

445618
## πŸ’‘ 3. New "Semantic Non-Null" type, usurping `!` syntax
446619

@@ -505,6 +678,29 @@ day-to-day work.
505678
- βœ… Error capture positions unchanged when error propagation enabled
506679
- [H][criteria-h]
507680
- 🚫 Implementation and spec simplicity.
681+
- [I][criteria-i]
682+
- βœ… Semantic non-null not relevant to inputs, so no reason to use directive in executable documents -> syntax unchanged.
683+
- [J][criteria-j]
684+
- ⚠️ Local reasoning holds for all but the schema authors; this is enabled
685+
through the use of client-generated SDL reflecting client extensions and
686+
error propagation behavior. For schema authors, local reasoning in the
687+
source SDL returns whether a field is nullable or non-nullable, but does
688+
not differentiate between _semantically_ non-nullable and _strictly_
689+
non-nullable.
690+
- [K][criteria-k]
691+
- βœ… Introspection backwards compatible via `__Field.type(includeSemanticNonNull: Boolean! = false)`
692+
- [L][criteria-l]
693+
- βœ… Proposal encourages consumers to use client-produced SDL which only uses traditional nullability (`Type`/`Type!`)
694+
- [M][criteria-m]
695+
- ⚠️ You can use the same SDL everywhere, but that's not what this solution
696+
encourages.
697+
- [N][criteria-n]
698+
- βœ… Indicates semantically non-null and strictly non-null types separately
699+
- [O][criteria-o]
700+
- βœ… Client syntax unchanged
701+
- [P][criteria-p]
702+
- βœ… There are no drawbacks to adding semantically non-nullable fields
703+
508704

509705
## πŸ’‘ 4. New "Semantic Non-Null" type, with `?` used for nullable types
510706

@@ -544,6 +740,23 @@ directive is present, and a `?` symbol is used to indicate a nullable position.
544740
- βœ… Error capture positions unchanged when error propagation enabled
545741
- [H][criteria-h]
546742
- 🚫 Implementation and spec simplicity.
743+
- [I][criteria-i]
744+
- 🚫 Clients will need to move to using new syntax (`Type?`/`Type`) or have syntax incongruent with schema SDL
745+
- [J][criteria-j]
746+
- 🚫 The nullability of `Type` cannot be determined without checking for a document directive
747+
- [K][criteria-k]
748+
- βœ… Introspection backwards compatible via `__Field.type(includeSemanticNonNull: Boolean! = false)`
749+
- [L][criteria-l]
750+
- ❔
751+
- [M][criteria-m]
752+
- ❔
753+
- [N][criteria-n]
754+
- βœ… Indicates semantically non-null and strictly non-null types separately
755+
- [O][criteria-o]
756+
- βœ… Clients must opt in to new syntax with document directive
757+
- [P][criteria-p]
758+
- βœ… There are no drawbacks to adding semantically non-nullable fields
759+
547760

548761
## πŸ’‘ 5. Use non-null in semantically non-nullable places and encourage disabling error propagation
549762

@@ -571,3 +784,19 @@ This proposal relies on the ability of clients to opt out of error propagation;
571784
- 🚫 Using non-null in more positions will change the error boundary positions when error propagation is enabled.
572785
- [H][criteria-h]
573786
- βœ… Implementation and spec simplicity.
787+
- [I][criteria-i]
788+
- βœ… No change
789+
- [J][criteria-j]
790+
- βœ… No change
791+
- [K][criteria-k]
792+
- βœ… No change
793+
- [L][criteria-l]
794+
- βœ… No change
795+
- [M][criteria-m]
796+
- βœ… No change
797+
- [N][criteria-n]
798+
- 🚫 Solution actually decreases value when error propagation is enabled due to lowered resilience to errors.
799+
- [O][criteria-o]
800+
- 🚫 Changing fields to strictly non-null causes errors to propagate further, a breaking change. (Duplicate of G.)
801+
- [P][criteria-p]
802+
- 🚫 Though the solution states it encourages the adoption of non-null, doing so is a breaking change for existing clients and so adopters are likely to hesitate when marking some semantically non-nullable positions as such

0 commit comments

Comments
Β (0)