Skip to content

Commit 68681f6

Browse files
committed
cleanup require invalid fields
1 parent b61b00d commit 68681f6

File tree

1 file changed

+39
-14
lines changed

1 file changed

+39
-14
lines changed

spec/Section 4 -- Composition.md

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5841,58 +5841,72 @@ ERROR
58415841

58425842
**Formal Specification**
58435843

5844-
- Let {schema} be the merged composite execution schema.
5845-
- Let {compositeTypes} be the set of all composite types in {schema}.
5844+
- Let {schemas} be all source schemas.
5845+
- Let {compositeTypes} be the set of all composite types in {schemas}.
58465846
- For each {composite} in {compositeTypes}:
58475847
- Let {fields} be the set of fields on {composite}.
58485848
- Let {arguments} be the set of all arguments on {fields}.
58495849
- For each {argument} in {arguments}:
58505850
- If {argument} is **not** annotated with `@require`:
58515851
- Continue
5852+
- Let {schema} be the schema that defines {argument}.
5853+
- Let {declaringField} be the field that defines {argument}.
5854+
- Let {declaringType} be the type that defines {declaringField}.
5855+
- Let {otherSchemas} be the set of all {schemas} excluding {schema}.
58525856
- Let {fieldArg} be the string value of the `field` argument of the
58535857
`@require` directive on {argument}.
58545858
- Let {parsedFieldArg} be the parsed selection map from {fieldArg}.
5855-
- {ValidateSelectionMap(parsedFieldArg, parentType)} must be true.
5859+
- {ValidateSelectionMap(parsedFieldArg, declaringType, otherSchemas)} must
5860+
be true.
58565861

5857-
ValidateSelectionMap(selectionMap, parentType):
5862+
ValidateSelectionMap(selectionMap, declaringType, schemas):
58585863

58595864
- For each {selection} in {selectionMap}:
5860-
- Let {field} be the field selected by {selection} on {parentType}.
5861-
- If {field} is **not** defined on {parentType}:
5865+
- Let {possibleTypes} be the set of all possible types for {declaringType} in
5866+
{schemas}.
5867+
- Let {field} be the first field selected by {selection} on any
5868+
{possibleTypes}.
5869+
- If no {field} is found
58625870
- return false
58635871
- Let {fieldType} be the type of {field}.
58645872
- If {fieldType} is not a scalar type
5865-
- Let {subSelections} be the selections in {selection}
5866-
- If {subSelections} is empty
5873+
- Let {subSelectionSet} be the selection set of {selection}
5874+
- If {subSelectionSet} is empty
58675875
- return false
5868-
- If {ValidateSelectionMap(subSelections, fieldType)} is false
5876+
- If {ValidateSelectionMap(subSelectionSet, fieldType, schemas)} is false
58695877
- return false
58705878
- return true
58715879

58725880
**Explanatory Text**
58735881

58745882
Even if the selection map for `@require(field: "")` is syntactically valid, its
5875-
contents must also be valid within the composed schema. Fields must exist on the
5876-
parent type for them to be referenced by `@require`. In addition, fields
5877-
requiring unknown fields break the valid usage of `@require`, leading to a
5878-
`REQUIRE_INVALID_FIELDS` error.
5883+
contents must also be valid. Required fields must exist on the parent type in a
5884+
**different schema than the one defining the requirement** for them to be
5885+
referenced by `@require`. Additionally, requiring unknown fields invalidates
5886+
`@require`, resulting in a `REQUIRE_INVALID_FIELDS` error.
58795887

58805888
**Examples**
58815889

58825890
In the following example, the `@require` directive's `field` argument is a valid
58835891
selection set and satisfies the rule.
58845892

58855893
```graphql example
5894+
## Schema A
58865895
type User @key(fields: "id") {
58875896
id: ID!
5888-
name: String!
58895897
profile(name: String! @require(field: "name")): Profile
58905898
}
58915899

58925900
type Profile {
58935901
id: ID!
58945902
name: String
58955903
}
5904+
5905+
## Schema B
5906+
type User @key(fields: "id") {
5907+
id: ID!
5908+
name: String
5909+
}
58965910
```
58975911

58985912
In this counter-example, the `@require` directive does not have a valid
@@ -5920,6 +5934,17 @@ type Book {
59205934
}
59215935
```
59225936

5937+
In the following counter-example, the `@require` directive references a field from itself
5938+
(`Book.size`) which is not allowed. This results in a `REQUIRE_INVALID_FIELDS` error.
5939+
5940+
```graphql counter-example
5941+
type Book {
5942+
id: ID!
5943+
size: Int
5944+
pages(pageSize: Int @require(field: "size")): Int
5945+
}
5946+
```
5947+
59235948
### Validate Shareable Directives
59245949

59255950
#### Invalid Field Sharing

0 commit comments

Comments
 (0)