At a glance
- Identifier: #710
- Stage: RFC 0 / Strawman
- Champion: @chemisus
- Latest activity: Added to WG agenda on 2020-05-07
- Spec PR: https://github.com/graphql/graphql-spec/pull/710
Spec PR description
Problem: There are a few issues one runs into when using the introspection of a schema to get the return types of fields.
- nested query required for each NonNull and List means never guaranteed to get the full return type of a field on the first query
- requires more effort than necessary to piece together the return type of a field
Example:
type StringTable {
values: [[String!]!]!
}
As seen, StringTable is a simple container for a string[][]. The query just to find that out would look like this:
{
__type(name:"StringTable") {
kind
name
fields {
name
type {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
}
}
}
}
}
}
}
}
}
The output of which is as follows:
{
"data": {
"__type": {
"kind": "OBJECT",
"name": "StringTable",
"fields": [
{
"name": "values",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String"
}
}
}
}
}
}
}
]
}
}
}
All that just for just one field is unnecessary. It's even worse when viewing several fields for several types. If there were another List added for some reason, the query would need to be modified to add another level and resent. To avoid the process of modifying and resending queries, the initial query usually includes several levels to start.
Solution: I'd like to propose adding two fields to __Type: namedType and punctuatedName.
extend type __Type {
namedType: __Type!
punctuatedName: String!
}
namedType returns the underlying named type, found by continually unwrapping the type until a named type is found - i.e. the type with all non-null and list wrappers removed.
punctuatedName returns the name of the (wrapped) type as it would be expressed in GraphQL's IDL; i.e. the underlying named types' name with additional punctuators from wrapping Lists and NonNulls.
Depending on the type's kind, namedType would resolve to the following:
- Lists & NonNulls:
namedType := ofType.namedType - All other types:
namedTypewould yield a reference to itself.
Depending on the type's kind, punctuatedName would resolve to the following:
- Lists:
punctuatedName := '[' + ofType.punctuatedName + ']' - NonNulls:
punctuatedName := ofType.punctuatedName + '!' - All other types:
punctuatedName := name
Adding namedType and punctuatedName to __Type would allow for the following query:
{
__type(name:"StringTable") {
kind
name
fields {
name
type {
name
namedType {
kind
name
}
punctuatedName
}
}
}
}
Which would yield the following output:
{
"data": {
"__type": {
"kind": "OBJECT",
"name": "StringTable",
"fields": [
{
"name": "values",
"type": {
"name": null,
"namedType": {
"kind": "SCALAR",
"name": "String"
},
"punctuatedName": "[[String!]!]!"
}
}
]
}
}
}
As seen, that is a much more compact query and response. It would also guarantee to provide a return information about the fields base type or punctuated name for any given field on the first request.
Timeline
- Added to WG agenda on 2020-05-07
- Mentioned in WG notes on 2020-05-07
- 2 commits pushed on 2020-04-29:
- chemisus committed "Update spec/Section 4 -- Introspection.md"
- chemisus committed "Update spec/Section 4 -- Introspection.md"
- Spec PR created on 2020-04-17 by chemisus
- Commit pushed on 2020-04-17 by chemisus: add spec for punctuatedName and namedType