Skip to content

Commit 346bd32

Browse files
authored
Move Provides Invalid Fields to source schema validation (#206)
1 parent 388d8ab commit 346bd32

File tree

1 file changed

+78
-80
lines changed

1 file changed

+78
-80
lines changed

spec/Section 4 -- Composition.md

Lines changed: 78 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,6 +1856,84 @@ type User @key(fields: "id") {
18561856
}
18571857
```
18581858

1859+
#### Provides Invalid Fields
1860+
1861+
**Error Code**
1862+
1863+
`PROVIDES_INVALID_FIELDS`
1864+
1865+
**Severity**
1866+
1867+
ERROR
1868+
1869+
**Formal Specification**
1870+
1871+
- Let {schema} be the source schema to validate.
1872+
- Let {fieldsWithProvides} be the set of all fields annotated with the
1873+
`@provides` directive in {schema}.
1874+
- For each {field} in {fieldsWithProvides}:
1875+
- Let {fieldsArg} be the string value of the `fields` argument of the
1876+
`@provides` directive on {field}.
1877+
- Let {parsedFieldSelectionSet} be the parsed field selection set from
1878+
{fieldsArg}.
1879+
- Let {returnType} be the return type of {field}.
1880+
- {ValidateFieldSelectionSet(parsedFieldSelectionSet, returnType)} must be
1881+
true.
1882+
1883+
ValidateFieldSelectionSet(fieldSelectionSet, parentType):
1884+
1885+
- For each {selection} in {fieldSelectionSet}:
1886+
- Let {selectedField} be the field selected by {selection} in {parentType}.
1887+
- If {selectedField} does not exist on {parentType}:
1888+
- return false
1889+
- Let {selectedType} be the type of {selectedField}
1890+
- If {selectedType} is an {INTERFACE} or {OBJECT} type
1891+
- Let {subSelectionSet} be the field selection set of {selection}
1892+
- If {subSelectionSet} is empty
1893+
- return false
1894+
- If {ValidateFieldSelectionSet(subSelectionSet, fieldType)} is false
1895+
- return false
1896+
- return true
1897+
1898+
**Explanatory Text**
1899+
1900+
Even if the `@provides(fields: "")` argument is well-formed syntactically, the
1901+
selected fields must actually exist on the return type of the field. Invalid
1902+
field referencese.g., selecting non-existent fields, referencing fields on the
1903+
wrong type, or incorrectly omitting required nested selectionslead to a
1904+
`PROVIDES_INVALID_FIELDS` error.
1905+
1906+
**Examples**
1907+
1908+
In the following example, the `@provides` directive references a valid field
1909+
(`hobbies`) on the `UserDetails` type.
1910+
1911+
```graphql example
1912+
type User @key(fields: "id") {
1913+
id: ID!
1914+
details: UserDetails @provides(fields: "hobbies")
1915+
}
1916+
1917+
type UserDetails {
1918+
hobbies: [String]
1919+
}
1920+
```
1921+
1922+
In the following counter-example, the `@provides` directive specifies a field
1923+
named `unknownField` which is not defined on `UserDetails`. This raises a
1924+
`PROVIDES_INVALID_FIELDS` error.
1925+
1926+
```graphql counter-example
1927+
type User @key(fields: "id") {
1928+
id: ID!
1929+
details: UserDetails @provides(fields: "unknownField")
1930+
}
1931+
1932+
type UserDetails {
1933+
hobbies: [String]
1934+
}
1935+
```
1936+
18591937
#### Provides Invalid Fields Type
18601938

18611939
**Error Code**
@@ -6225,86 +6303,6 @@ type Person {
62256303
}
62266304
```
62276305

6228-
### Validate Provides Directives
6229-
6230-
#### Provides Invalid Fields
6231-
6232-
**Error Code**
6233-
6234-
`PROVIDES_INVALID_FIELDS`
6235-
6236-
**Severity**
6237-
6238-
ERROR
6239-
6240-
**Formal Specification**
6241-
6242-
- Let {schema} be the merged composite execution schema.
6243-
- Let {fieldsWithProvides} be the set of all fields annotated with the
6244-
`@provides` directive in {schema}.
6245-
- For each {field} in {fieldsWithProvides}:
6246-
- Let {fieldsArg} be the string value of the `fields` argument of the
6247-
`@provides` directive on {field}.
6248-
- Let {parsedFieldSelectionSet} be the parsed field selection set from
6249-
{fieldsArg}.
6250-
- Let {returnType} be the return type of {field}.
6251-
- {ValidateFieldSelectionSet(parsedFieldSelectionSet, returnType)} must be
6252-
true.
6253-
6254-
ValidateFieldSelectionSet(fieldSelectionSet, parentType):
6255-
6256-
- For each {selection} in {fieldSelectionSet}:
6257-
- Let {selectedField} be the field selected by {selection} in {parentType}.
6258-
- If {selectedField} does not exist on {parentType}:
6259-
- return false
6260-
- Let {selectedType} be the type of {selectedField}
6261-
- If {selectedType} is a composite type
6262-
- Let {subSelectionSet} be the field selection set of {selection}
6263-
- If {subSelectionSet} is empty
6264-
- return false
6265-
- If {ValidateFieldSelectionSet(subSelectionSet, fieldType)} is false
6266-
- return false
6267-
- return true
6268-
6269-
**Explanatory Text**
6270-
6271-
Even if the `@provides(fields: "")` argument is well-formed syntactically, the
6272-
selected fields must actually exist on the return type of the field. Invalid
6273-
field referencese.g., selecting non-existent fields, referencing fields on the
6274-
wrong type, or incorrectly omitting required nested selectionslead to a
6275-
`PROVIDES_INVALID_FIELDS` error.
6276-
6277-
**Examples**
6278-
6279-
In the following example, the `@provides` directive references a valid field
6280-
(`hobbies`) on the `UserDetails` type.
6281-
6282-
```graphql example
6283-
type User @key(fields: "id") {
6284-
id: ID!
6285-
details: UserDetails @provides(fields: "hobbies")
6286-
}
6287-
6288-
type UserDetails {
6289-
hobbies: [String]
6290-
}
6291-
```
6292-
6293-
In the following counter-example, the `@provides` directive specifies a field
6294-
named `unknownField` which is not defined on `UserDetails`. This raises a
6295-
`PROVIDES_INVALID_FIELDS` error.
6296-
6297-
```graphql counter-example
6298-
type User @key(fields: "id") {
6299-
id: ID!
6300-
details: UserDetails @provides(fields: "unknownField")
6301-
}
6302-
6303-
type UserDetails {
6304-
hobbies: [String]
6305-
}
6306-
```
6307-
63086306
### Validate Require Directives
63096307

63106308
#### Require Invalid Fields

0 commit comments

Comments
 (0)