Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the links in the semantic nullability RFC #1665

Merged
merged 2 commits into from
Feb 20, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions rfcs/SemanticNullability.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ Guiding Principles. The scores are:

## 🎯 A. GraphQL should be able to indicate which nullable fields should become non-nullable when error propagation is disabled

[criteria-a]: #-a-graphql-should-be-able-to-indicate-which-nullable-fields-should-become-non-nullable-when-error-propagation-is-disabled

The promise of this RFC - the reflection of the semantic nullability of the
fields without compromising requests with error propagation enabled via the
differentiation of a "null if and only if an error occurs" type.
Expand All @@ -232,6 +234,8 @@ Criteria score: 🥇

## 🎯 B. Existing executable documents should retain validity and meaning

[criteria-b]: #-b-existing-executable-documents-should-retain-validity-and-meaning

Users should be able to adopt semantic nullability into an existing schema, and
when doing so all existing operations should remain valid, and should have the
same meaning as they always did.
Expand All @@ -244,6 +248,8 @@ Criteria score: 🥇

## 🎯 C. Unadorned type should mean nullable

[criteria-c]: #-c-unadorned-type-should-mean-nullable

GraphQL has been public for 10 years and there's a lot of content out there
noting that GraphQL types are nullable by default (unadorned type is nullable)
and our changes should not invalidate this content.
Expand All @@ -256,6 +262,8 @@ Criteria score: 🥈

## 🎯 D. Syntax should be obvious to programmers

[criteria-d]: #-d-syntax-should-be-obvious-to-programmers

The GraphQL languages similarity to JSON is one of its strengths, making it
immediately feel familiar. Syntax used should feel obvious to developers new to
GraphQL.
Expand All @@ -268,6 +276,8 @@ Criteria score: 🥈

## 🎯 E. Syntax used in SDL and in executable documents should be consistent with SDL

[criteria-e]: #-e-syntax-used-in-sdl-and-in-executable-documents-should-be-consistent-with-sdl

When a user wishes to replace the value for an input field or argument with a
variable in their GraphQL operation, the type syntax should be either identical
or similar, and should carry the same meaning.
Expand All @@ -280,6 +290,8 @@ Criteria score: 🥇

## 🎯 F. Alternative syntaxes should not cause confusion

[criteria-f]: #-f-alternative-syntaxes-should-not-cause-confusion

Where a proposal allows alternative syntaxes to be used, the two syntaxes should
not cause confusion.

Expand All @@ -291,6 +303,8 @@ Criteria score: 🥇

## 🎯 G. Error propagation boundaries should not change in existing executable documents

[criteria-g]: #-g-error-propagation-boundaries-should-not-change-in-existing-executable-documents

An expansion of B, this states that the proposal will not change where errors
propagate to when error propagation is enabled (i.e. existing documents will
still keep errors local to the same positions that they did when they were
Expand All @@ -308,6 +322,8 @@ path for legacy apps, the tradeoff might be acceptable.

## 🎯 H. Implementation and spec simplicity

[criteria-h]: #-h-implementation-and-spec-simplicity

The implementation required to make the proposal work should be simple.

| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
Expand All @@ -318,6 +334,8 @@ Criteria score: 🥈

## 🎯 I. Syntax used in executable documents should be unchanged

[criteria-i]: #-i-syntax-used-in-executable-documents-should-be-unchanged

Executable documents do not differentiate between semantic and strict non-null
since inputs never handle "errors" ("null only on error" is the same as "not
null" on input). As such, there's no benefit to clients for the syntax of
Expand All @@ -331,6 +349,8 @@ Criteria score: 🥇

## 🎯 J. Type reasoning should remain local

[criteria-j]: #-j-type-reasoning-should-remain-local

The type of a field (`foo: Int`) can be determined by looking at the field and
its type; the reader should not have to read a document or schema directive to
determine how the type should be interpreted.
Expand All @@ -343,6 +363,8 @@ Criteria score: 🥇

## 🎯 K. Introspection must be backwards compatible

[criteria-k]: #-k-introspection-must-be-backwards-compatible

We do not want to break existing tooling.

| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
Expand All @@ -353,6 +375,8 @@ Criteria score: 🥇

## 🎯 L. General GraphQL consumers should only need to think about nullable vs non-nullable

[criteria-l]: #-l-general-graphql-consumers-should-only-need-to-think-about-nullable-vs-non-nullable

Schema authors and client frameworks can handle different types of nullability based around
error handling and error propagation, but consumers (frontend developers) should only need
to deal with nullable or non-nullable as presented to them by their client framework of choice.
Expand All @@ -367,6 +391,8 @@ Criteria score: 🥇

## 🎯 M. The SDL should have exactly one form used by all producers and consumers

[criteria-m]: #-m-the-sdl-should-have-exactly-one-form-used-by-all-producers-and-consumers

The SDL should not be influenced by client features such as local extensions and
error propagation mechanics, and should always represent the true full source
schema SDL.
Expand All @@ -381,6 +407,8 @@ Criteria score: 🥇

## 🎯 N. The solution should add value even with error propagation enabled

[criteria-n]: #-n-the-solution-should-add-value-even-with-error-propagation-enabled

Even when error propagation is enabled, it's valuable to be able to tell the
difference between a field that is truly (semantically) nullable, and one
that's only nullable because errors may occur. GraphQL-TOE can be used in such
Expand All @@ -395,6 +423,8 @@ Criteria score: 🥇

## 🎯 O. Should not have breaking changes for existing executable documents

[criteria-o]: #-o-should-not-have-breaking-changes-for-existing-executable-documents

It should be possible to enable the solution without negatively impacting
existing deployed clients.

Expand All @@ -419,6 +449,8 @@ Criteria score: X (not considered - covered by B and G)

## 🎯 P. The solution should result in users marking all semantically non-null fields as such

[criteria-p]: #-p-the-solution-should-result-in-users-marking-all-semantically-non-null-fields-as-such

When a field returns data that the business logic dictates does not and will
never return a legitimate (non-error) null, the schema authors should have no
hesitation over marking it as semantically non-nullable - and thus all
Expand All @@ -440,6 +472,8 @@ Criteria score: 🥇

## 🎯 Q. Migrating the unadorned output type to other forms of nullability should be non-breaking

[criteria-q]: #-q-migrating-the-unadorned-output-type-to-other-forms-of-nullability-should-be-non-breaking

The default (unadorned) type should be a type that you can migrate away from,
once nullability expectations become more concrete, without breaking existing
client queries.
Expand Down Expand Up @@ -480,6 +514,8 @@ rest of the document. New solutions must be added to the end of the list.

## 💡 1. New "Semantic Non-Null" type, represented by `*`

[solution-1]: #-1-new-semantic-non-null-type-represented-by-

**Champion**: @benjie

- Spec edits: https://github.com/graphql/graphql-spec/pull/1065
Expand Down Expand Up @@ -559,6 +595,8 @@ have been discussed the choice of symbol comes down mostly to aesthetics.

## 💡 2. "Strict Semantic Nullability"

[solution-2]: #-2-strict-semantic-nullability

**Champion**: @leebyron

- Discussion: https://github.com/graphql/graphql-wg/discussions/1410
Expand Down Expand Up @@ -617,6 +655,8 @@ symbol) to indicate that a position may semantically be null.

## 💡 3. New "Semantic Non-Null" type, usurping `!` syntax

[solution-3]: #-3-new-semantic-non-null-type-usurping--syntax

**Champion**: @benjie

This proposal is similar to proposal 1, but:
Expand Down Expand Up @@ -704,6 +744,8 @@ day-to-day work.

## 💡 4. New "Semantic Non-Null" type, with `?` used for nullable types

[solution-4]: #-4-new-semantic-non-null-type-with--used-for-nullable-types

**Champion**: @twof

This proposal builds on solution 3, but with a syntactic shuffle such that the
Expand Down Expand Up @@ -760,6 +802,8 @@ directive is present, and a `?` symbol is used to indicate a nullable position.

## 💡 5. Use non-null in semantically non-nullable places and encourage disabling error propagation

[solution-5]: #-5-use-non-null-in-semantically-non-nullable-places-and-encourage-disabling-error-propagation

**Champion**: @martinbonnin

- Discussion: https://github.com/graphql/nullability-wg/discussions/85
Expand Down