Skip to content

Proposal: Add namedType and punctuatedName to __Type #709

Closed
@chemisus

Description

@chemisus

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: namedType would 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions