Skip to content

Commit 57f2894

Browse files
binaryseedleebyron
authored andcommitted
[Input Union] Criteria scoring (#668)
* Evaluate criteria * First ranking of criteria * Evaluate M * scores in grid * re-score H * re-score 5-A * Note the ranked order
1 parent e0ef987 commit 57f2894

File tree

1 file changed

+63
-23
lines changed

1 file changed

+63
-23
lines changed

rfcs/InputUnion.md

Lines changed: 63 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,12 @@ Solutions are evaluated and scored using a simple 3 part scale. A solution may h
192192

193193
Passing or failing a specific criteria is NOT the final word. Both the Criteria _and_ the Solutions are up for debate.
194194

195+
Criteria have been given a "score" according to their relative importance in solving the problem laid out in this RFC while adhering to the GraphQL Spec Guiding Principles. The scores are:
196+
197+
* 🥇 Gold - A must-have
198+
* 🥈 Silver - A nice-to-have
199+
* 🥉 Bronze - Not necessary
200+
195201
## 🎯 A. GraphQL should contain a polymorphic Input type
196202

197203
The premise of this RFC - GraphQL should contain a polymorphic Input type.
@@ -200,6 +206,8 @@ The premise of this RFC - GraphQL should contain a polymorphic Input type.
200206
|----|----|----|----|----|
201207
||||| ⚠️ |
202208

209+
Criteria score: 🥇
210+
203211
## 🎯 B. Input polymorphism matches output polymorphism
204212

205213
Any data structure that can be modeled with output type polymorphism should be able to be mirrored with Input polymorphism. Minimal transformation of outputs should be required to send a data structure back as inputs.
@@ -210,6 +218,8 @@ Any data structure that can be modeled with output type polymorphism should be a
210218
|----|----|----|----|----|
211219
| ✅⚠️ ||| ✅⚠️ | 🚫 |
212220

221+
Criteria score: 🥇
222+
213223
## 🎯 C. Doesn't inhibit schema evolution
214224

215225
The GraphQL specification mentions the ability to evolve your schema as one of its core values:
@@ -221,6 +231,8 @@ Adding a new member type to an Input Union or doing any non-breaking change to e
221231
|----|----|----|----|----|
222232
||| 🚫 | ⚠️ ||
223233

234+
Criteria score: 🥇
235+
224236
## 🎯 D. Any member type restrictions are validated in schema
225237

226238
If a solution places any restrictions on member types, compliance with these restrictions should be fully validated during schema building (analagous to how interfaces enforce restrictions on member types).
@@ -229,6 +241,8 @@ If a solution places any restrictions on member types, compliance with these res
229241
|----|----|----|----|----|
230242
||||||
231243

244+
Criteria score: 🥇
245+
232246
## 🎯 E. A member type may be a Leaf type
233247

234248
In addition to containing Input types, member type may also contain Leaf types like `Scalar`s or `Enum`s.
@@ -241,6 +255,8 @@ In addition to containing Input types, member type may also contain Leaf types l
241255
|----|----|----|----|----|
242256
| 🚫 | 🚫 | ✅⚠️ | 🚫 ||
243257

258+
Criteria score: 🥉
259+
244260
## 🎯 F. Migrating a field to a polymorphic input type is non-breaking
245261

246262
Since the input object type is now a member of the input union, existing input objects being sent through should remain valid.
@@ -252,6 +268,8 @@ Since the input object type is now a member of the input union, existing input o
252268
|----|----|----|----|----|
253269
| ✅⚠️ | ✅⚠️ || ⚠️ ||
254270

271+
Criteria score: 🥉
272+
255273
## 🎯 G. Input unions may include other input unions
256274

257275
To ease development.
@@ -262,6 +280,8 @@ To ease development.
262280
|----|----|----|----|----|
263281
||||||
264282

283+
Criteria score: 🥉
284+
265285
## 🎯 H. Input unions should accept plain data
266286

267287
Clients should be able to pass "natural" input data to unions without specially formatting it or adding extra metadata.
@@ -272,6 +292,8 @@ Clients should be able to pass "natural" input data to unions without specially
272292
|----|----|----|----|----|
273293
| ⚠️ | ⚠️ ||| ⚠️ |
274294

295+
Criteria score: 🥈
296+
275297
## 🎯 I. Input unions should be easy to upgrade from existing solutions
276298

277299
Many people in the wild are solving the need for input unions with validation at run-time (e.g. using the "tagged union" pattern). Formalising support for these existing patterns in a non-breaking way would enable existing schemas to become retroactively more type-safe.
@@ -284,14 +306,18 @@ Note: This criteria is similar to [F. Migrating a field to a polymorphic input
284306
|----|----|----|----|----|
285307
| ✅⚠️ | ✅⚠️ || ⚠️ ||
286308

309+
Criteria score: 🥉
310+
287311
## 🎯 J. A GraphQL schema that supports input unions can be queried by older GraphQL clients
288312

289-
Preferably without a loss of or change in functionality.
313+
Preferably without a loss of or change in previously supported functionality.
290314

291315
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
292316
|----|----|----|----|----|
293317
||||||
294318

319+
Criteria score: 🥇
320+
295321
## 🎯 K. Input unions should be expressed efficiently in the query and on the wire
296322

297323
The less typing and fewer bytes transmitted, the better.
@@ -303,6 +329,8 @@ The less typing and fewer bytes transmitted, the better.
303329
|----|----|----|----|----|
304330
||||||
305331

332+
Criteria score: 🥉
333+
306334
## 🎯 L. Input unions should be performant for servers
307335

308336
Ideally a server does not have to do much computation to determine which concrete type is represented by an input.
@@ -313,13 +341,17 @@ Ideally a server does not have to do much computation to determine which concret
313341
|----|----|----|----|----|
314342
||||||
315343

344+
Criteria score: 🥉
345+
316346
## 🎯 M. Existing SDL parsers are backwards compatible with SDL additions
317347

318348
Common tools that parse GraphQL SDL should not fail when pointed at a schema which supports polymorphic input types.
319349

320350
| [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
321351
|----|----|----|----|----|
322-
||||||
352+
| 🚫 | 🚫 | 🚫 | 🚫 ||
353+
354+
Criteria score: 🥈
323355

324356
## 🎯 N. Existing code generated tooling is backwards compatible with Introspection additions
325357

@@ -329,6 +361,8 @@ For example, GraphiQL should successfully render when pointed at a schema which
329361
|----|----|----|----|----|
330362
||||||
331363

364+
Criteria score: 🥈
365+
332366
# 🚧 Possible Solutions
333367

334368
The community has imagined a variety of possible solutions, synthesized here.
@@ -403,7 +437,7 @@ type Mutation {
403437
* [L. Input unions should be performant for servers][criteria-l]
404438
* ❔ Not evaluated
405439
* [M. Existing SDL parsers are backwards compatible with SDL additions][criteria-m]
406-
* ❔ Not evaluated
440+
* 🚫 Parsers will not recognize the `inputunion` keyword
407441
* [N. Existing code generated tooling is backwards compatible with Introspection additions][criteria-n]
408442
* ❔ Not evaluated
409443

@@ -511,8 +545,6 @@ input DogInput {
511545
}
512546
```
513547

514-
* A `default` type may be defined, for which specifying the `__typename` is not required. This enables a field to migration from an `Input` to an `Input Union`
515-
516548
### ⚖️ Evaluation
517549

518550
* [A. GraphQL should contain a polymorphic Input type][criteria-a]
@@ -539,7 +571,7 @@ input DogInput {
539571
* [L. Input unions should be performant for servers][criteria-l]
540572
* ❔ Not evaluated
541573
* [M. Existing SDL parsers are backwards compatible with SDL additions][criteria-m]
542-
* ❔ Not evaluated
574+
* 🚫 Parsers will not recognize the `inputunion` keyword
543575
* [N. Existing code generated tooling is backwards compatible with Introspection additions][criteria-n]
544576
* ❔ Not evaluated
545577

@@ -624,7 +656,7 @@ type Mutation {
624656
* [L. Input unions should be performant for servers][criteria-l]
625657
* ❔ Not evaluated
626658
* [M. Existing SDL parsers are backwards compatible with SDL additions][criteria-m]
627-
* ❔ Not evaluated
659+
* 🚫 Parsers will not recognize the `inputunion` keyword
628660
* [N. Existing code generated tooling is backwards compatible with Introspection additions][criteria-n]
629661
* ❔ Not evaluated
630662

@@ -714,7 +746,7 @@ input DogInput {
714746
* [L. Input unions should be performant for servers][criteria-l]
715747
* ❔ Not evaluated
716748
* [M. Existing SDL parsers are backwards compatible with SDL additions][criteria-m]
717-
* ❔ Not evaluated
749+
* 🚫 Parsers will not recognize the `inputunion` keyword
718750
* [N. Existing code generated tooling is backwards compatible with Introspection additions][criteria-n]
719751
* ❔ Not evaluated
720752

@@ -764,7 +796,7 @@ type Mutation {
764796
### ⚖️ Evaluation
765797

766798
* [A. GraphQL should contain a polymorphic Input type][criteria-a]
767-
* ⚠️ This isn't a polymorphic input type, it's extra schema-level validation for an intermediate type
799+
* Tagged union is a valid version of a polymorphic type
768800
* [B. Input polymorphism matches output polymorphism][criteria-b]
769801
* 🚫 The shape of the input type is forced to have a different structure than the corresponding output type.
770802
* [C. Doesn't inhibit schema evolution][criteria-c]
@@ -805,20 +837,20 @@ A quick glance at the evaluation results. Remember that passing or failing a spe
805837

806838
| | [1][solution-1] | [2][solution-2] | [3][solution-3] | [4][solution-4] | [5][solution-5] |
807839
| -- | -- | -- | -- | -- | -- |
808-
| [A][criteria-a] | ✅ | ✅ | ✅ | ✅ | ⚠️ |
809-
| [B][criteria-b] | ✅⚠️ | ✅ | ✅ | ✅⚠️ | 🚫 |
810-
| [C][criteria-c] | ✅ | ✅ | 🚫 | ⚠️ | ✅ |
811-
| [D][criteria-d] | ✅ | ✅ | ✅ | ✅ | ✅ |
812-
| [E][criteria-e] | 🚫 | 🚫 | ✅⚠️ | 🚫 | ✅ |
813-
| [F][criteria-f] | ✅⚠️ | ✅⚠️ | ✅ | ⚠️ | ✅ |
814-
| [G][criteria-g] | ❔ | ❔ | ❔ | ❔ | ❔ |
815-
| [H][criteria-h] | ⚠️ | ⚠️ | ✅ | ✅ | ⚠️ |
816-
| [I][criteria-i] | ✅⚠️ | ✅⚠️ | ✅ | ⚠️ | ✅ |
817-
| [J][criteria-j] | ✅ | ✅ | ✅ | ✅ | ✅ |
818-
| [K][criteria-k] | ❔ | ❔ | ❔ | ❔ | ✅ |
819-
| [L][criteria-l] | ❔ | ❔ | ❔ | ❔ | ✅ |
820-
| [M][criteria-m] | ❔ | | | | ✅ |
821-
| [N][criteria-n] | ❔ | ❔ | ❔ | ❔ | ✅ |
840+
| [A][criteria-a] 🥇 | ✅ | ✅ | ✅ | ✅ | ⚠️ |
841+
| [B][criteria-b] 🥇 | ✅⚠️ | ✅ | ✅ | ✅⚠️ | 🚫 |
842+
| [C][criteria-c] 🥇 | ✅ | ✅ | 🚫 | ⚠️ | ✅ |
843+
| [D][criteria-d] 🥇 | ✅ | ✅ | ✅ | ✅ | ✅ |
844+
| [E][criteria-e] 🥉 | 🚫 | 🚫 | ✅⚠️ | 🚫 | ✅ |
845+
| [F][criteria-f] 🥉 | ✅⚠️ | ✅⚠️ | ✅ | ⚠️ | ✅ |
846+
| [G][criteria-g] 🥉 | ❔ | ❔ | ❔ | ❔ | ❔ |
847+
| [H][criteria-h] 🥈 | ⚠️ | ⚠️ | ✅ | ✅ | ⚠️ |
848+
| [I][criteria-i] 🥉 | ✅⚠️ | ✅⚠️ | ✅ | ⚠️ | ✅ |
849+
| [J][criteria-j] 🥇 | ✅ | ✅ | ✅ | ✅ | ✅ |
850+
| [K][criteria-k] 🥉 | ❔ | ❔ | ❔ | ❔ | ✅ |
851+
| [L][criteria-l] 🥉 | ❔ | ❔ | ❔ | ❔ | ✅ |
852+
| [M][criteria-m] 🥈 | 🚫 | 🚫 | 🚫 | 🚫 | ✅ |
853+
| [N][criteria-n] 🥈 | ❔ | ❔ | ❔ | ❔ | ✅ |
822854

823855
[criteria-a]: #-a-graphql-should-contain-a-polymorphic-input-type
824856
[criteria-b]: #-b-input-polymorphism-matches-output-polymorphism
@@ -840,3 +872,11 @@ A quick glance at the evaluation results. Remember that passing or failing a spe
840872
[solution-3]: #-3-order-based-discrimination
841873
[solution-4]: #-4-structural-uniqueness
842874
[solution-5]: #-5-one-of-tagged-union
875+
876+
# ☑️ Decision Time!
877+
878+
According to a simple [weight ranking](https://docs.google.com/spreadsheets/d/1ymKqI6BSTHGGHkf9IDjo0EJmOqMryS-uQRwDV77OF5g/edit?usp=sharing), here are the solutions in order:
879+
880+
* [2][solution-2]
881+
* [1][solution-1] / [5][solution-5]
882+
* [3][solution-3] / [4][solution-4]

0 commit comments

Comments
 (0)