Skip to content

Commit 807019c

Browse files
committed
Overheal README with greater detail
1 parent fdffa2e commit 807019c

File tree

1 file changed

+153
-26
lines changed

1 file changed

+153
-26
lines changed

README.md

Lines changed: 153 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,70 @@
11
# GraphQL SOCK
22

3-
SOCK: **Semantic Output Conversion Kit**
3+
SOCK: **Semantic Output Conversion Kit** - converting semantic-nullability
4+
schemas into traditional schemas to support existing tooling (e.g. codegen).
45

56
## What is it?
67

78
**Takes as input a GraphQL SDL and outputs a derived SDL wherein all
8-
semantic-non-null type modifiers have either been removed
9-
(`semantic-to-nullable`) or have been replaced with strict (traditional)
10-
non-null modifiers (`semantic-to-strict`).**
9+
semantic-non-null type modifiers have either been removed (semantic to nullable)
10+
or have been replaced with strict (traditional) non-null modifiers (semantic to
11+
strict).**
12+
13+
### Semantic nullability
1114

1215
In the latest proposals around semantic nullability, we introduce a new
1316
"Semantic Non Null" type modifier that means that the value is "null only on
14-
error". However, not all tools support this yet, so this library contains tools
15-
to convert a modern SDL into a more traditional one, to be used for code
16-
generation and other such functionality.
17+
error" (i.e. it will never be `null` unless an error has occurred). However, not
18+
all tools support this yet, so this library contains tools to convert a schema
19+
or SDL that supports semantic nullability into a more traditional one, to be
20+
used for code generation and other such functionality.
21+
22+
Which command you use will depend on your setup; if you're using a client that
23+
prevents you from reading error nulls (e.g. by throwing when you read from an
24+
errored field like [`graphql-toe`](https://github.com/graphile/graphql-toe)
25+
does, or otherwise) then you'll want `semantic-to-strict` to really capitalize
26+
on the benefits of semantic nullability.
27+
28+
If you just want to use a semantic nullability SDL with traditional tools and
29+
clients that don't yet understand semantic nullability, then
30+
`semantic-to-nullable` will just strip out the semantic-non-null types for you.
31+
32+
This library supports both the `@semanticNonNull` directive (which should work
33+
universally, but is likely to be a temporary placeholder), and the
34+
`GraphQLSemanticNonNull` wrapper type (if your version of GraphQL.js supports
35+
it, otherwise it will degrade gracefully to only supporting the directive).
36+
37+
### `@semanticNonNull` directive
38+
39+
For the directive, the two conversions work like this:
40+
41+
| Mode | Input type | Output type |
42+
| -------------------- | --------------------------------------- | ----------- |
43+
| semantic-to-nullable | `Int @semanticNonNull` | `Int` |
44+
| semantic-to-strict | `Int @semanticNonNull` | `Int!` |
45+
| semantic-to-nullable | `[Int] @semanticNonNull(levels: [1])` | `[Int]` |
46+
| semantic-to-strict | `[Int] @semanticNonNull(levels: [1])` | `[Int!]` |
47+
| semantic-to-nullable | `[Int] @semanticNonNull(levels: [0,1])` | `[Int]` |
48+
| semantic-to-strict | `[Int] @semanticNonNull(levels: [0,1])` | `[Int!]!` |
49+
50+
### `GraphQLSemanticNonNull` wrapper type
51+
52+
How the `GraphQLSemanticNonNull` type is represented syntactically in SDL is yet
53+
to be determined by the working group, but this library doesn't care about that
54+
since it uses the schema directly. For the sake of this README we'll use the
55+
originally proposed
56+
[asterisk syntax](https://github.com/graphql/graphql-spec/pull/1065).
57+
58+
The above examples using asterisk syntax would be:
1759

18-
Which command you use will depend on your setup; if you're using `graphql-toe`
19-
then you'll want `semantic-to-strict` to really capitalize on the benefits of
20-
semantic nullability. If you just want to use a semantic nullability SDL with
21-
traditional tools that don't yet understand it, then `semantic-to-nullable` will
22-
just strip out the semantic-non-null types for you.
60+
| Mode | Input type | Output type |
61+
| -------------------- | ---------- | ----------- |
62+
| semantic-to-nullable | `Int*` | `Int` |
63+
| semantic-to-strict | `Int*` | `Int!` |
64+
| semantic-to-nullable | `[Int*]` | `[Int]` |
65+
| semantic-to-strict | `[Int*]` | `[Int!]` |
66+
| semantic-to-nullable | `[Int*]*` | `[Int]` |
67+
| semantic-to-strict | `[Int*]*` | `[Int!]!` |
2368

2469
## Installation
2570

@@ -33,28 +78,110 @@ pnpm install --save graphql-sock
3378

3479
## Usage
3580

36-
### `semantic-to-nullable`
81+
Consider this "input schema" which uses both the `@semanticNonNull` directive
82+
and the `*` syntax (for syntax support, you will need to be running a
83+
[compatible version of graphql.js](https://github.com/graphql/graphql-js/pull/4192#issuecomment-2351103549)):
84+
85+
### Input schema
86+
87+
```graphql
88+
type Query {
89+
someList: [Int] @semanticNonNull(levels: [0, 1])
90+
someOtherList: [String*]*
91+
}
92+
```
93+
94+
### Semantic to nullable
95+
96+
**If a value is "null only on error" then it _can_ be null.**
97+
98+
This conversion strips all semantic-non-null type wrappers from the SDL, making
99+
a schema that appears as it traditionally would. This means that you won't reap
100+
any of the benefits of semantic nullability, but you can support existing tools
101+
and clients without needing to update their code.
102+
103+
#### Output schema
104+
105+
The input schema would have all the semantic non-null types removed:
106+
107+
```graphql
108+
type Query {
109+
someList: [Int]
110+
someOtherList: [String]
111+
}
112+
```
113+
114+
#### CLI
37115

38-
If a value is "null only on error" then it can be null. This conversion strips
39-
all semantic-non-null type wrappers from the SDL, making a schema that appears
40-
as it traditionally would. This means that you won't reap any of the benefits of
41-
semantic nullability, but you can support existing tools.
116+
From the CLI, use the `semantic-to-nullable` command to convert an SDL with
117+
semantic nullability into an SDL without semantic nullability, where all
118+
semantic non-null positions have been removed:
42119

43120
```
44121
semantic-to-nullable -i input.graphql -o output.graphql
45122
```
46123

47-
### `semantic-to-strict`
124+
#### Library
125+
126+
Use the `semanticToNullable` export to create a copy of a schema with all the
127+
semantic non-null types removed:
128+
129+
```ts
130+
import { semanticToNullable } from "graphql-sock";
131+
import { sourceSchema as inputSchema } from "./my-schema";
132+
133+
export const outputSchema = semanticToNullable(inputSchema);
134+
```
135+
136+
### Semantic to strict
137+
138+
**Error handling clients prevent users from reading "error-nulls" (e.g. by
139+
throwing an error), so semantically non-nullable positions are non-nullable for
140+
these clients.**
141+
142+
If you're using "Throw On Error" (e.g. via
143+
[graphql-toe](https://github.com/graphile/graphql-toe)) or a similar technique
144+
then when you read from an errored field an error will be thrown, preventing you
145+
from reading the underlying `null`.
146+
147+
**Think of semantically non-null fields as "null only on error;" if you throw on
148+
errors, then they're never null!**
149+
150+
As such, this position becomes equivalent to a traditional non-null for you, so
151+
this conversion converts all semantic-non-null type wrappers into traditional
152+
(strict) non-null wrappers. Your type generators can therefore generate fewer
153+
nullables, and your frontend engineers have to do fewer null checks and are
154+
therefore happier.
155+
156+
#### Output schema
157+
158+
The input schema would become:
159+
160+
```graphql
161+
type Query {
162+
someList: [Int!]!
163+
someOtherList: [String!]!
164+
}
165+
```
166+
167+
#### CLI
48168

49-
If you're using [graphql-toe](https://github.com/graphile/graphql-toe) or a
50-
similar technique that means that when you read from an errored field the error
51-
will be thrown, then it will not be possible for you to read a `null` from a
52-
"null only on error" position. As such, this position becomes equivalent to a
53-
traditional non-null for you, so this conversion converts all semantic-non-null
54-
type wrappers into traditional non-null wrappers. Your type generators can
55-
therefore generate fewer nullables, and your frontend engineers have to do fewer
56-
null checks and are therefore happier.
169+
From the CLI, use the `semantic-to-strict` command to convert an SDL with
170+
semantic nullability into an SDL without semantic nullability, where all
171+
semantic non-null positions have become strictly non-null:
57172

58173
```
59174
semantic-to-strict -i input.graphql -o output.graphql
60175
```
176+
177+
#### Library
178+
179+
Use the `semanticToStrict` export to create a copy of a schema with all the
180+
semantic non-null types replaced with strict (traditional) non-null types:
181+
182+
```ts
183+
import { semanticToStrict } from "graphql-sock";
184+
import { schema as sourceSchema } from "./my-schema";
185+
186+
export const schema = semanticToStrict(sourceSchema);
187+
```

0 commit comments

Comments
 (0)