You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This factors out a step from `CompleteValue()` about "coercing" a value to a formal sub-algorithm `CoerceInternalValue()` that mirrors the language used in `ResolveAbstractType()` - both refer to "internal methods" provided for each type, which is in fact how the reference implementation applies this coercion behavior.
As editorial, this provides a place to expand on the behavior and purpose as well as link back to the relevant subsection from the type system section.
This also makes a *very important* clarification. The previous step read that if coercion failed then "otherwise null". This actually described a much older version of the reference implementation which did not always produce errors for failed coercion. Years back the reference implementation and the spec changed the "result coercion" subsections of all the built-in scalars to clearly state that field errors are thrown if coercion fails. This step now creates ambiguitity about which behavior is correct - returning null or throwing a field error? In practice both may be correct because of the error handling behavior - but we should be clear that the returned null is a result of that error behavior rather than it being an explicit behavior that's part of `CompleteValue()`. The new pulled out sub-algo makes it clear that the return type must be valid or a field error is produced - which is exactly the behavior described by each built-in scalar.
* Let {subSelectionSet} be the result of calling {MergeSelectionSets(fields)}.
667
666
* Return the result of evaluating {ExecuteSelectionSet(subSelectionSet, objectType, result, variableValues)} *normally* (allowing for parallelization).
668
667
668
+
**Coercing Results**
669
+
670
+
The primary purpose of value completion is to ensure that the values returned by
671
+
field resolvers are valid according to the GraphQL type system and a service's
672
+
schema. This "dynamic type checking" allows GraphQL to provide consistent
673
+
guarantees about returned types atop any service's internal runtime.
674
+
675
+
See the Scalars [Result Coercion and Serialization](#sec-Scalars.Result-Coercion-and-Serialization)
676
+
sub-section for more detailed information about how GraphQL's built-in scalars
677
+
coerce result values.
678
+
679
+
CoerceResult(leafType, value):
680
+
* Assert {value} is not {null}.
681
+
* Return the result of calling the internal method provided by the type
682
+
system for determining the "result coercion" of {leafType} given the value
683
+
{value}. This internal method must return a valid value for the
684
+
type and not {null}. Otherwise throw a field error.
685
+
686
+
Note: If a field resolver returns {null} then it is handled within
687
+
{CompleteValue()} before {CoerceResult()} is called. Therefore both the input
688
+
and output of {CoerceResult()} must not be {null}.
689
+
669
690
**Resolving Abstract Types**
670
691
671
692
When completing a field with an abstract return type, that is an Interface or
0 commit comments