Commit 63a508c
authored
RFC: Fix ambiguity with null variable values and default values (#418)
* RFC: Fix ambiguity with null variable values and default values
> This is a **behavioral change** which changes how explicit `null` values interact with variable and argument default values. This also changes a validation rule which makes the rule more strict.
There is currently ambiguity and inconsistency in how `null` values are coerced and resolved as part of variable values, default values, and argument values. This inconsistency and ambiguity can allow for `null` values to appear at non-null arguments, which might result in unforseen null-pointer-errors.
This appears in three distinct but related issues:
**Validation: All Variable Usages are Allowed**
The explicit value `null` may be used as a default value for a variable with a nullable type, however this rule asks to treat a variable's type as non-null if it has a default value. Instead this rule should specifically only treat the variable's type as non-null if the default value is not `null`.
Additionally, the `AreTypesCompatible` algorithm is underspecificied, which could lead to further misinterpretation of this validation rule.
**Coercing Variable Values**
`CoerceVariableValues()` allows the explicit `null` value to be used instead of a default value. This can result in a null value flowing to a non-null argument due to the validation rule mentioned above. Instead a default value must be used even when an explicit `null` value is provided. This is also more consistent with the explanation for validation rule "Variable Default Value Is Allowed"
Also, how to treat an explicit `null` value is currently underspecified. While an input object explains that a `null` value should result in an explicit `null` value at the input object field, there is no similar explaination for typical scalar input types. Instead, `CoerceVariableValues()` should explicitly handle the `null` value to make it clear a `null` is the resulting value in the `coercedValues` Map.
**Coercing Argument Values**
The `CoerceArgumentValues()` algorithm is intentionally similar to `CoerceVariableValues()` and suffers from the same inconsistency. Explicit `null` values should not take precedence over default values, and should also be explicitly handled rather than left to underspecified input scalar coercion.
* Updated based on feedback.
This updates this proposal to be a bit broader in scope however much narrower in breaking behavior changes.
Mirroring the changes in graphql/graphql-js#1274, this update better defines the difference between a "required" and "non-null" argument / input field as a non-null typed argument / input-field with a default value is no longer required. As such the validation rule which prohibited queries from using non-null variables and default values has been removed. This also adds clarity to the input field validation - this rule has existed in the GraphQL.js reference implementation however was found missing within the spec.
This also updates the CoerceVariableValues() and CoerceArgumentValues() algorithms to retain explicit null values overriding a default value (minimizing breaking changes), however critically adding additional protection to CoerceArgumentValues() to explicitly block null values from variables - thus allowing the older pattern of passing a nullable variable into a non-null argument while limiting the problematic case of an explicit null value at runtime.
* One step further towards the idealized "from scratch" proposal, this makes it more explicitly clear that changing the effective type of a variable definition is only relevent when supporting legacy clients and suggests that new services should not use this behavior.
I like that this balances a clear description of how this rule should work for existing services along with a stricter and therefore safer future path for new services.
* Editing AreTypesCompatible() to avoid trailing "Otherwise return false" statements for easier reading. Functionality is equivalent.
* Update "All Variable Usages are Allowed" to remove breaking change.
Also attempts to improve clarity and formatting and adds an example case.
* Make related changes to input object coercion rules
* Final review edits1 parent 2b2467a commit 63a508c
File tree
3 files changed
+188
-129
lines changed- spec
3 files changed
+188
-129
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1263 | 1263 | | |
1264 | 1264 | | |
1265 | 1265 | | |
1266 | | - | |
1267 | | - | |
| 1266 | + | |
| 1267 | + | |
1268 | 1268 | | |
1269 | | - | |
| 1269 | + | |
1270 | 1270 | | |
1271 | 1271 | | |
1272 | | - | |
1273 | | - | |
1274 | | - | |
1275 | | - | |
1276 | | - | |
1277 | | - | |
1278 | | - | |
1279 | | - | |
1280 | | - | |
1281 | | - | |
1282 | | - | |
1283 | | - | |
1284 | | - | |
| 1272 | + | |
| 1273 | + | |
| 1274 | + | |
| 1275 | + | |
| 1276 | + | |
| 1277 | + | |
| 1278 | + | |
| 1279 | + | |
| 1280 | + | |
| 1281 | + | |
| 1282 | + | |
| 1283 | + | |
| 1284 | + | |
| 1285 | + | |
| 1286 | + | |
| 1287 | + | |
| 1288 | + | |
| 1289 | + | |
| 1290 | + | |
| 1291 | + | |
| 1292 | + | |
| 1293 | + | |
| 1294 | + | |
| 1295 | + | |
1285 | 1296 | | |
1286 | 1297 | | |
1287 | 1298 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
676 | 676 | | |
677 | 677 | | |
678 | 678 | | |
| 679 | + | |
679 | 680 | | |
680 | 681 | | |
681 | 682 | | |
| |||
710 | 711 | | |
711 | 712 | | |
712 | 713 | | |
713 | | - | |
| 714 | + | |
714 | 715 | | |
715 | 716 | | |
716 | 717 | | |
717 | 718 | | |
718 | | - | |
719 | | - | |
720 | | - | |
721 | | - | |
| 719 | + | |
| 720 | + | |
| 721 | + | |
| 722 | + | |
| 723 | + | |
722 | 724 | | |
723 | 725 | | |
724 | 726 | | |
725 | 727 | | |
726 | 728 | | |
727 | 729 | | |
728 | 730 | | |
729 | | - | |
730 | | - | |
731 | | - | |
| 731 | + | |
| 732 | + | |
732 | 733 | | |
733 | 734 | | |
734 | 735 | | |
| |||
752 | 753 | | |
753 | 754 | | |
754 | 755 | | |
755 | | - | |
| 756 | + | |
756 | 757 | | |
757 | 758 | | |
758 | 759 | | |
759 | 760 | | |
760 | 761 | | |
761 | 762 | | |
762 | 763 | | |
763 | | - | |
| 764 | + | |
| 765 | + | |
764 | 766 | | |
765 | 767 | | |
766 | 768 | | |
767 | | - | |
| 769 | + | |
768 | 770 | | |
769 | 771 | | |
770 | 772 | | |
| |||
1358 | 1360 | | |
1359 | 1361 | | |
1360 | 1362 | | |
| 1363 | + | |
| 1364 | + | |
| 1365 | + | |
| 1366 | + | |
| 1367 | + | |
| 1368 | + | |
| 1369 | + | |
| 1370 | + | |
| 1371 | + | |
| 1372 | + | |
| 1373 | + | |
| 1374 | + | |
| 1375 | + | |
| 1376 | + | |
| 1377 | + | |
| 1378 | + | |
| 1379 | + | |
| 1380 | + | |
| 1381 | + | |
| 1382 | + | |
| 1383 | + | |
| 1384 | + | |
| 1385 | + | |
| 1386 | + | |
| 1387 | + | |
1361 | 1388 | | |
1362 | 1389 | | |
1363 | 1390 | | |
| |||
1494 | 1521 | | |
1495 | 1522 | | |
1496 | 1523 | | |
1497 | | - | |
1498 | | - | |
1499 | | - | |
1500 | | - | |
1501 | | - | |
1502 | | - | |
1503 | | - | |
1504 | | - | |
1505 | | - | |
1506 | | - | |
1507 | | - | |
1508 | | - | |
1509 | | - | |
1510 | | - | |
1511 | | - | |
1512 | | - | |
1513 | | - | |
1514 | | - | |
1515 | | - | |
1516 | | - | |
1517 | | - | |
1518 | | - | |
1519 | | - | |
1520 | | - | |
1521 | | - | |
1522 | | - | |
1523 | | - | |
1524 | | - | |
1525 | | - | |
1526 | | - | |
1527 | | - | |
1528 | | - | |
1529 | | - | |
1530 | | - | |
1531 | | - | |
1532 | | - | |
1533 | | - | |
1534 | | - | |
1535 | 1524 | | |
1536 | 1525 | | |
1537 | 1526 | | |
| |||
1833 | 1822 | | |
1834 | 1823 | | |
1835 | 1824 | | |
1836 | | - | |
1837 | | - | |
1838 | | - | |
1839 | | - | |
1840 | | - | |
1841 | | - | |
1842 | | - | |
1843 | | - | |
1844 | | - | |
1845 | | - | |
1846 | | - | |
1847 | | - | |
1848 | | - | |
1849 | | - | |
| 1825 | + | |
| 1826 | + | |
| 1827 | + | |
| 1828 | + | |
| 1829 | + | |
| 1830 | + | |
| 1831 | + | |
| 1832 | + | |
| 1833 | + | |
| 1834 | + | |
| 1835 | + | |
| 1836 | + | |
| 1837 | + | |
| 1838 | + | |
| 1839 | + | |
| 1840 | + | |
| 1841 | + | |
| 1842 | + | |
| 1843 | + | |
| 1844 | + | |
| 1845 | + | |
| 1846 | + | |
| 1847 | + | |
| 1848 | + | |
| 1849 | + | |
| 1850 | + | |
| 1851 | + | |
| 1852 | + | |
| 1853 | + | |
| 1854 | + | |
| 1855 | + | |
| 1856 | + | |
| 1857 | + | |
| 1858 | + | |
| 1859 | + | |
| 1860 | + | |
| 1861 | + | |
| 1862 | + | |
| 1863 | + | |
1850 | 1864 | | |
1851 | 1865 | | |
1852 | 1866 | | |
| |||
1890 | 1904 | | |
1891 | 1905 | | |
1892 | 1906 | | |
1893 | | - | |
1894 | | - | |
1895 | | - | |
1896 | | - | |
1897 | | - | |
1898 | | - | |
1899 | | - | |
1900 | | - | |
1901 | | - | |
1902 | | - | |
1903 | | - | |
1904 | 1907 | | |
1905 | 1908 | | |
1906 | 1909 | | |
| |||
1925 | 1928 | | |
1926 | 1929 | | |
1927 | 1930 | | |
1928 | | - | |
1929 | 1931 | | |
| 1932 | + | |
| 1933 | + | |
| 1934 | + | |
| 1935 | + | |
| 1936 | + | |
| 1937 | + | |
| 1938 | + | |
| 1939 | + | |
| 1940 | + | |
| 1941 | + | |
| 1942 | + | |
| 1943 | + | |
| 1944 | + | |
| 1945 | + | |
| 1946 | + | |
| 1947 | + | |
| 1948 | + | |
| 1949 | + | |
| 1950 | + | |
| 1951 | + | |
| 1952 | + | |
| 1953 | + | |
| 1954 | + | |
| 1955 | + | |
| 1956 | + | |
| 1957 | + | |
| 1958 | + | |
| 1959 | + | |
| 1960 | + | |
| 1961 | + | |
| 1962 | + | |
| 1963 | + | |
0 commit comments