@@ -383,6 +383,46 @@ IsOutputType(type):
383383 - Return {true }.
384384- Return {false }.
385385
386+ ### Input Coercion
387+
388+ CoerceInputValue (type, value, variableValues):
389+
390+ - Assert : {IsInputType (type)}.
391+ - If {type } is a Non -Null type :
392+ - If {value } is {null }, raise a _coercion failure_ .
393+ - Let {innerType } be the _inner type_ of {type }.
394+ - Return the result of calling {CoerceInputValue (innerType, value,
395+ variableValues)}.
396+ - If {value } is {null }, return {null }.
397+ - If {type } is a List type , return the result of {CoerceInputListValue (type,
398+ value, variableValues)}.
399+ - If {type } is an Input Object type , return the result of
400+ {CoerceInputObjectValue (type, value, variableValues)}.
401+ - If {type } is an Enum type , return the result of {CoerceInputEnumValue (type,
402+ value)}.
403+ - Otherwise , return the result of {CoerceScalarValue (type, value)}.
404+
405+ Input coercion defines the requirements for how an value is transformed into a
406+ canonical form expected by the internal GraphQL service , including the
407+ resolution of any variables (see {ResolveVariable ()}). This allows GraphQL to
408+ provide consistent guarantees about inputs to field resolution atop any
409+ service 's internal runtime or network serialization .
410+
411+ :: Failure to meet these requirements results in _coercion failure_ , which may
412+ occur during different phases of a GraphQL service , each of which results in a
413+ different type of error . As a result , each phase specifically describes how to
414+ handle a coercion failure :
415+
416+ - During schema construction (i.e. a default value for an argument definition),
417+ failure results in an invalid schema.
418+ - During document validation (i.e. a value literal directly within an
419+ operation), failure results in document invalidation, which raises a _request
420+ error_.
421+ - During coercion of values provided for variables as part of a request, failure
422+ results in a _request error_.
423+ - During coercion of field arguments, failure results in an _execution error_,
424+ however validation and variable value coercion should make this uncommon.
425+
386426### Type Extensions
387427
388428TypeExtension :
@@ -502,10 +542,17 @@ information on the serialization of scalars in common JSON and other formats.
502542
503543**Input Coercion**
504544
545+ CoerceScalarValue (scalarType , value):
546+
547+ - Assert : value is not {null }, which is already handled in {CoerceInputValue ()}.
548+ - Return the result of calling the internal method provided by the type system
549+ for determining the “input coercion ” of {scalarType } given the value {value }.
550+ This internal method must return a valid value for the type and not {null }.
551+ Otherwise raise a _coercion failure_ .
552+
505553If a GraphQL service expects a scalar type as input to an argument , coercion is
506554observable and the rules must be well defined . If an input value does not match
507- a coercion rule, a _request error_ must be raised (input values are validated
508- before execution begins ).
555+ a coercion rule , it results in _coercion failure_ .
509556
510557GraphQL has different constant literals to represent integer and floating -point
511558input values , and coercion rules may apply differently depending on which type
@@ -516,8 +563,9 @@ floating-point values, they are interpreted as an integer input value if they
516563have an empty fractional part (ex. `1.0`) and otherwise as floating -point input
517564value .
518565
519- For all types below , with the exception of Non -Null , if the explicit value
520- {null } is provided , then the result of input coercion is {null }.
566+ Note : {null } is a valid input value for all scalar types except those wrapped by
567+ a _Non -Null type_ , however {null } value coercion is handled in
568+ {CoerceInputValue ()} before {CoerceScalarValue ()} is called .
521569
522570### Int
523571
@@ -544,10 +592,9 @@ greater than or equal to 2<sup>31</sup>, an _execution error_ should be raised.
544592**Input Coercion **
545593
546594When expected as an input type , only integer input values are accepted . All
547- other input values , including strings with numeric content , must raise a request
548- error indicating an incorrect type . If the integer input value represents a
549- value less than -2<sup >31</sup > or greater than or equal to 2<sup >31</sup >, a
550- _request error_ should be raised .
595+ other input values , including strings with numeric content result in _coercion
596+ failure_ indicating an incorrect type . Input values less than -2<sup >31</sup > or
597+ greater than or equal to 2<sup >31</sup > result in _coercion failure_ .
551598
552599Note : Numeric integer values larger than 32-bit should either use String or a
553600custom -defined Scalar type , as not all platforms and transports support encoding
@@ -578,10 +625,10 @@ coerced to {Float} and must raise an _execution error_.
578625When expected as an input type , both integer and float input values are
579626accepted . Integer input values are coerced to Float by adding an empty
580627fractional part , for example `1.0` for the integer input value `1`. All other
581- input values , including strings with numeric content , must raise a _request
582- error_ indicating an incorrect type . If the input value otherwise represents a
583- value not representable by finite IEEE 754 (e.g. {NaN}, {Infinity}, or a value
584- outside the available precision), a _request error_ must be raised .
628+ input values , including strings with numeric content , result in _coercion
629+ failure_ indicating an incorrect type . Input values not representable by finite
630+ IEEE 754 (e.g. {NaN}, {Infinity}, or a value outside the available precision)
631+ result in _coercion failure_ .
585632
586633### String
587634
@@ -604,8 +651,7 @@ value, or the string `"1"` for the integer `1`.
604651**Input Coercion **
605652
606653When expected as an input type , only valid Unicode string input values are
607- accepted . All other input values must raise a _request error_ indicating an
608- incorrect type .
654+ accepted . All other input values result in _coercion failure_ .
609655
610656### Boolean
611657
@@ -624,7 +670,7 @@ Examples of this may include returning `true` for non-zero numbers.
624670**Input Coercion **
625671
626672When expected as an input type , only boolean input values are accepted . All
627- other input values must raise a _request error_ indicating an incorrect type .
673+ other input values result in _coercion failure_ .
628674
629675### ID
630676
@@ -647,9 +693,8 @@ When coercion is not possible they must raise an _execution error_.
647693
648694When expected as an input type , any string (such as `"4" `) or integer (such as
649695`4` or `-4`) input value should be coerced to ID as appropriate for the ID
650- formats a given GraphQL service expects . Any other input value , including float
651- input values (such as `4.0`), must raise a _request error_ indicating an
652- incorrect type .
696+ formats a given GraphQL service expects . All other input values , including float
697+ input values (such as `4.0`), result in _coercion failure_ .
653698
654699### Scalar Extensions
655700
@@ -914,7 +959,7 @@ executor, see [Value Completion](#sec-Value-Completion).
914959
915960**Input Coercion**
916961
917- Objects are never valid inputs.
962+ Object types are never valid inputs. See [Input Objects]( #sec-Input-Objects) .
918963
919964**Type Validation**
920965
@@ -938,8 +983,8 @@ of rules must be adhered to by every Object type in a GraphQL schema.
938983 returns {true }.
939984 4. If argument type is Non -Null and a default value is not defined :
940985 1. The `@deprecated ` directive must not be applied to this argument .
941- 5. If the argument has a default value it must be compatible with
942- { argumentType } as per the coercion rules for that type .
986+ 5. If the argument has a default value , { CoerceInputValue (argumentType,
987+ defaultValue)} must not result in _coercion failure_ .
9439883. An object type may declare that it implements one or more unique interfaces .
9449894. An object type must be a super -set of all interfaces it implements :
945990 1. Let this object type be {objectType }.
@@ -1044,6 +1089,26 @@ May return the result:
10441089The type of an object field argument must be an input type (any type except an
10451090Object, Interface, or Union type).
10461091
1092+ **Default Values **
1093+
1094+ GetDefaultValue (inputValueDefinition):
1095+
1096+ - Assert : {inputValueDefinition } has a {DefaultValue }, as this is only called
1097+ when true .
1098+ - Let {inputType } be the type of {inputValueDefinition }.
1099+ - Let {defaultValue } be the default value of {inputValueDefinition }
1100+ - Return the result of {CoerceInputValue (inputType, defaultValue, null)}. (Note :
1101+ default values must not contain variable references )
1102+
1103+ A default value may be provided for a field argument , input object field , or
1104+ variable definitions . If at runtime a value is not provided , the coerced default
1105+ value is used instead .
1106+
1107+ Note : Implementations are encouraged to optimize the coercion of a default value
1108+ by doing so only once and caching the resulting coerced value . This should not
1109+ result in request execution _coercion failure_ since all default values should
1110+ be validated before a request .
1111+
10471112### Field Deprecation
10481113
10491114Fields in an object may be marked as deprecated as deemed necessary by the
@@ -1291,6 +1356,8 @@ Interface types have the potential to be invalid if incorrectly defined.
12911356 arguments may share the same name .
12921357 3. The argument must accept a type where {IsInputType (argumentType)}
12931358 returns {true }.
1359+ 4. If a argument has a default value , {CoerceInputValue (argumentType,
1360+ defaultValue)} must not result in _coercion failure_ .
129413613. An interface type may declare that it implements one or more unique
12951362 interfaces , but may not implement itself .
129613634. An interface type must be a super -set of all interfaces it implements :
@@ -1517,15 +1584,24 @@ reasonable coercion is not possible they must raise an _execution error_.
15171584
15181585**Input Coercion **
15191586
1520- GraphQL has a constant literal to represent enum input values . GraphQL string
1521- literals must not be accepted as an enum input and instead raise a request
1522- error .
1587+ CoerceInputEnumValue (type, value):
1588+
1589+ - Assert : value is not {null }, which is already handled in {CoerceInputValue ()}.
1590+ - If {value } represents a name (such as {EnumValue}), let {name } be the name of
1591+ {value }:
1592+ - If Enum {type } has a member named {name }, let it be {member }:
1593+ - Return the internal value representing {member }.
1594+ - Otherwise raise a _coercion failure_ .
1595+
1596+ GraphQL has a constant literal , {EnumValue }, used to represent enum input
1597+ values . GraphQL {StringValue } literals must not be accepted as an enum input and
1598+ instead result in a _coercion failure_ .
15231599
15241600Variable transport serializations which have a different representation for
15251601non -string symbolic values (for example,
15261602[EDN](https ://github .com /edn -format /edn )) should only allow such values as enum
15271603input values . Otherwise , for most transport serializations that do not , strings
1528- may be interpreted as the enum input value with the same name .
1604+ may be interpreted as the enum member of the same name .
15291605
15301606**Type Validation **
15311607
@@ -1649,11 +1725,47 @@ type of an Object or Interface field.
16491725
16501726**Input Coercion **
16511727
1728+ CoerceInputObjectValue (type, value, variableValues):
1729+
1730+ - If {value } is not an {ObjectValue } or map of values , raise a _coercion
1731+ failure_ .
1732+ - Let {coercedValues } be an empty map .
1733+ - Let {inputFieldDefinitions } be the input fields defined by {type }:
1734+ - For each {inputFieldDefinition } in {inputFieldDefinitions }:
1735+ - Let {inputFieldName } be the name of {inputFieldDefinition }.
1736+ - Let {inputFieldType } be the expected type of {inputFieldDefinition }.
1737+ - Assert : {IsInputType (inputFieldType)}, because of
1738+ [type validation ](#sec-Input-Objects.Type-Validation).
1739+ - If {value} has an entry with name {inputFieldName}, let {inputFieldValue} be
1740+ its value :
1741+ - If {inputFieldValue } is a {Variable }, let {variableName} be its name :
1742+ - Let {isProvided }, {variableValue} be the result of
1743+ {ResolveVariable(type, variableName, variableValues)}.
1744+ - If {isProvided } is {true }, add an entry to {coercedValues } named
1745+ {inputFieldName } with the value {variableValue }.
1746+ - Otherwise if {inputFieldDefinition } has a default value , add an entry to
1747+ {coercedValues } named {inputFieldName } with the value
1748+ {GetDefaultValue (inputFieldDefinition)}.
1749+ - Otherwise :
1750+ - Let {coercedValue } be the result of {CoerceInputValue (inputFieldType,
1751+ inputFieldValue, variableValues)}.
1752+ - Add an entry to {coercedValues } named {inputFieldName } with the value
1753+ {coercedValue }.
1754+ - Otherwise if {inputFieldDefinition } has a default value , add an entry to
1755+ {coercedValues } named {inputFieldName } with the value
1756+ {GetDefaultValue (inputFieldDefinition)}.
1757+ - Otherwise if {inputFieldType } is a Non -Null type , raise an _coercion
1758+ failure_ .
1759+ - Return {coercedValues }.
1760+
1761+ Note : This algorithm is very similar to {CoerceArgumentValues ()}, as both are
1762+ defined with {InputValueDefinition }.
1763+
16521764The value for an input object should be an input object literal or an unordered
1653- map supplied by a variable , otherwise a _request error_ must be raised . In
1765+ map supplied by a variable , otherwise it results in _coercion failure_ . In
16541766either case , the input object literal or unordered map must not contain any
1655- entries with names not defined by a field of this input object type , otherwise a
1656- request error must be raised .
1767+ entries with names not defined by a field of this input object type , otherwise
1768+ it results in _coercion failure_ .
16571769
16581770The result of coercion is an unordered map with an entry for each field both
16591771defined by the input object type and for which a value exists . The resulting map
@@ -1723,6 +1835,9 @@ input ExampleInputObject {
17231835 returns {true }.
17241836 4. If input field type is Non -Null and a default value is not defined :
17251837 1. The `@deprecated ` directive must not be applied to this input field .
1838+ 5. If the input object field has a default value ,
1839+ {CoerceInputValue (inputObjectType, defaultValue)} must not result in
1840+ _coercion failure_ .
172618413. If an Input Object references itself either directly or through referenced
17271842 Input Objects , at least one of the fields in the chain of references must be
17281843 either a nullable or a List type .
@@ -1819,19 +1934,44 @@ about this behavior.
18191934
18201935**Input Coercion**
18211936
1937+ CoerceInputListValue(type, value, variableValues):
1938+
1939+ - Assert : value is not {null }, which is already handled in {CoerceInputValue ()}.
1940+ - Let {coercedValues } be an empty list .
1941+ - Let {itemType } be the _inner type_ of {type }.
1942+ - If {value } is a list :
1943+ - For each {itemValue } in {value }:
1944+ - If {itemValue } is a {Variable }, let {variableName } be its name :
1945+ - Let {isProvided }, {variableValue } be the result of
1946+ {ResolveVariable (type, variable, variableValues)}.
1947+ - Append {variableValue } to {coercedValues }. (Note : Variables without
1948+ provided values are replaced with {null })
1949+ - Otherwise :
1950+ - Let {coercedValue } be the result of {CoerceInputValue (itemType,
1951+ itemValue, variableValues)}.
1952+ - Append {coercedValue } to {coercedValues }.
1953+ - Otherwise :
1954+ - Let {coercedValue } be the result of {CoerceInputValue (itemType, value,
1955+ variableValues)}.
1956+ - Append {coercedValue } to {coercedValues }.
1957+ - Return {coercedValues }.
1958+
18221959When expected as an input , list values are accepted only when each item in the
18231960list can be accepted by the list 's item type .
18241961
1825- If the value passed as an input to a list type is _not_ a list and not the
1826- {null} value, then the result of input coercion is a list of size one, where the
1827- single item value is the result of input coercion for the list's item type on
1828- the provided value (note this may apply recursively for nested lists).
1962+ If the value passed as an input to a list type is _not_ a list ( and not the
1963+ {null} value) , then the result of input coercion is a list of size one , where
1964+ the single item value is the result of input coercion for the list 's item type
1965+ on the provided value (which may apply recursively for nested lists).
18291966
18301967This allows inputs which accept one or many arguments (sometimes referred to as
18311968"var args" ) to declare their input type as a list while for the common case of a
18321969single value , a client can just pass that value directly rather than
18331970constructing the list .
18341971
1972+ Variables provided as items within a list are resolved to their coerced runtime
1973+ value if provided , otherwise {null } is used in place of an unprovided value .
1974+
18351975Following are examples of input coercion with various list types and values :
18361976
18371977| Expected Type | Provided Value | Coerced Value |
@@ -1884,14 +2024,14 @@ within the Execution section.
18842024
18852025**Input Coercion**
18862026
1887- If an argument or input-object field of a Non-Null type is not provided, is
1888- provided with the literal value {null}, or is provided with a variable that was
1889- either not provided a value at runtime, or was provided the value {null}, then a
1890- _request error_ must be raised .
2027+ Non-null inputs are _required_, if an argument, variable, or input-object field
2028+ of a Non-Null type is not provided, is provided with the literal value {null},
2029+ or is provided with a variable that was either not provided a value at runtime,
2030+ or was provided the value {null}, it results in a _coercion failure_ .
18912031
18922032If the value provided to the Non-Null type is provided with a literal value
18932033other than {null}, or a Non-Null variable value, it is coerced using the input
1894- coercion for the wrapped type.
2034+ coercion for the wrapped type (see {CoerceInputValue()}) .
18952035
18962036A non -null argument cannot be omitted :
18972037
0 commit comments