Skip to content

Latest commit

 

History

History
427 lines (308 loc) · 10.9 KB

Section 4 -- Introspection.md

File metadata and controls

427 lines (308 loc) · 10.9 KB

Introspection

A GraphQL server supports introspection over its schema. This schema is queried using GraphQL itself, creating a powerful platform for tool-building.

Take an example query for a trivial app. In this case there is a User type with three fields: id, name, and birthday.

For example, given a server with the following type definition:

type User {
  id: String
  name: String
  birthday: Date
}

The query

{
  __type(name: "User") {
    name
    fields {
      name
      type {
        name
      }
    }
  }
}

would return

{
  "__type": {
    "name": "User",
    "fields": [
      {
        "name": "id",
        "type": { "name": "String" }
      },
      {
        "name": "name",
        "type": { "name": "String" }
      },
      {
        "name": "birthday",
        "type": { "name": "Date" }
      },
    ]
  }
}

General Principles

Naming conventions

Types and fields required by the GraphQL introspection system that are used in the same context as user-defined types and fields are prefixed with {"__"} two underscores. This in order to avoid naming collisions with user-defined GraphQL types. Conversely, GraphQL type system authors must not define any types, fields, arguments, or any other type system artifact with two leading underscores.

Documentation

All types in the introspection system provide a description field of type String to allow type designers to publish documentation in addition to capabilities. A GraphQL server may return the description field using Markdown syntax (as specified by CommonMark). Therefore it is recommended that any tool that displays description use a CommonMark-compliant Markdown renderer.

Deprecation

To support the management of backwards compatibility, GraphQL fields and enum values can indicate whether or not they are deprecated (isDeprecated: Boolean) and a description of why it is deprecated (deprecationReason: String).

Tools built using GraphQL introspection should respect deprecation by discouraging deprecated use through information hiding or developer-facing warnings.

Type Name Introspection

GraphQL supports type name introspection at any point within a query by the meta field __typename: String! when querying against any Object, Interface, or Union. It returns the name of the object type currently being queried.

This is most often used when querying against Interface or Union types to identify which actual type of the possible types has been returned.

This field is implicit and does not appear in the fields list in any defined type.

Schema Introspection

The schema introspection system is accessible from the meta-fields __schema and __type which are accessible from the type of the root of a query operation.

__schema: __Schema!
__type(name: String!): __Type

These fields are implicit and do not appear in the fields list in the root type of the query operation.

The schema of the GraphQL schema introspection system:

type __Schema {
  types: [__Type!]!
  queryType: __Type!
  mutationType: __Type
  subscriptionType: __Type
  directives: [__Directive!]!
}

type __Type {
  kind: __TypeKind!
  name: String
  description: String

  # OBJECT and INTERFACE only
  fields(includeDeprecated: Boolean = false): [__Field!]
  interfaces: [__Type!]

  # INTERFACE and UNION only
  possibleTypes: [__Type!]

  # ENUM only
  enumValues(includeDeprecated: Boolean = false): [__EnumValue!]

  # INPUT_OBJECT only
  inputFields: [__InputValue!]

  # NON_NULL and LIST only
  ofType: __Type
}

type __Field {
  name: String!
  description: String
  args: [__InputValue!]!
  type: __Type!
  isDeprecated: Boolean!
  deprecationReason: String
}

type __InputValue {
  name: String!
  description: String
  type: __Type!
  defaultValue: String
}

type __EnumValue {
  name: String!
  description: String
  isDeprecated: Boolean!
  deprecationReason: String
}

enum __TypeKind {
  SCALAR
  OBJECT
  INTERFACE
  UNION
  ENUM
  INPUT_OBJECT
  LIST
  NON_NULL
}

type __Directive {
  name: String!
  description: String
  locations: [__DirectiveLocation!]!
  args: [__InputValue!]!
}

enum __DirectiveLocation {
  QUERY
  MUTATION
  SUBSCRIPTION
  FIELD
  FRAGMENT_DEFINITION
  FRAGMENT_SPREAD
  INLINE_FRAGMENT
}

The __Type Type

__Type is at the core of the type introspection system. It represents scalars, interfaces, object types, unions, enums in the system.

__Type also represents type modifiers, which are used to modify a type that it refers to (ofType: __Type). This is how we represent lists, non-nullable types, and the combinations thereof.

Type Kinds

There are several different kinds of type. In each kind, different fields are actually valid. These kinds are listed in the __TypeKind enumeration.

Scalar

Represents scalar types such as Int, String, and Boolean. Scalars cannot have fields.

A GraphQL type designer should describe the data format and scalar coercion rules in the description field of any scalar.

Fields

  • kind must return __TypeKind.SCALAR.
  • name must return a String.
  • description may return a String or {null}.
  • All other fields must return {null}.

Object

Object types represent concrete instantiations of sets of fields. The introspection types (e.g. __Type, __Field, etc) are examples of objects.

Fields

  • kind must return __TypeKind.OBJECT.
  • name must return a String.
  • description may return a String or {null}.
  • fields: The set of fields query-able on this type.
    • Accepts the argument includeDeprecated which defaults to {false}. If {true}, deprecated fields are also returned.
  • interfaces: The set of interfaces that an object implements.
  • All other fields must return {null}.

Union

Unions are an abstract type where no common fields are declared. The possible types of a union are explicitly listed out in possibleTypes. Types can be made parts of unions without modification of that type.

Fields

  • kind must return __TypeKind.UNION.
  • name must return a String.
  • description may return a String or {null}.
  • possibleTypes returns the list of types that can be represented within this union. They must be object types.
  • All other fields must return {null}.

Interface

Interfaces are an abstract type where there are common fields declared. Any type that implements an interface must define all the fields with names and types exactly matching. The implementations of this interface are explicitly listed out in possibleTypes.

Fields

  • kind must return __TypeKind.INTERFACE.
  • name must return a String.
  • description may return a String or {null}.
  • fields: The set of fields required by this interface.
    • Accepts the argument includeDeprecated which defaults to {false}. If {true}, deprecated fields are also returned.
  • interfaces: The set of interfaces that an interface implements.
  • possibleTypes returns the list of types that implement this interface. They must be object types.
  • All other fields must return {null}.

Enum

Enums are special scalars that can only have a defined set of values.

Fields

  • kind must return __TypeKind.ENUM.
  • name must return a String.
  • description may return a String or {null}.
  • enumValues: The list of EnumValue. There must be at least one and they must have unique names.
    • Accepts the argument includeDeprecated which defaults to {false}. If {true}, deprecated enum values are also returned.
  • All other fields must return {null}.

Input Object

Input objects are composite types used as inputs into queries defined as a list of named input values.

For example the input object Point could be defined as:

input Point {
  x: Int
  y: Int
}

Fields

  • kind must return __TypeKind.INPUT_OBJECT.
  • name must return a String.
  • description may return a String or {null}.
  • inputFields: a list of InputValue.
  • All other fields must return {null}.

List

Lists represent sequences of values in GraphQL. A List type is a type modifier: it wraps another type instance in the ofType field, which defines the type of each item in the list.

Fields

  • kind must return __TypeKind.LIST.
  • ofType: Any type.
  • All other fields must return {null}.

Non-Null

GraphQL types are nullable. The value {null} is a valid response for field type.

A Non-null type is a type modifier: it wraps another type instance in the ofType field. Non-null types do not allow {null} as a response, and indicate required inputs for arguments and input object fields.

  • kind must return __TypeKind.NON_NULL.
  • ofType: Any type except Non-null.
  • All other fields must return {null}.

Combining List and Non-Null

List and Non-Null can compose, representing more complex types.

If the modified type of a List is Non-Null, then that List may not contain any {null} items.

If the modified type of a Non-Null is List, then {null} is not accepted, however an empty list is accepted.

If the modified type of a List is a List, then each item in the first List is another List of the second List's type.

A Non-Null type cannot modify another Non-Null type.

The __Field Type

The __Field type represents each field in an Object or Interface type.

Fields

  • name must return a String
  • description may return a String or {null}
  • args returns a List of __InputValue representing the arguments this field accepts.
  • type must return a __Type that represents the type of value returned by this field.
  • isDeprecated returns {true} if this field should no longer be used, otherwise {false}.
  • deprecationReason optionally provides a reason why this field is deprecated.

The __InputValue Type

The __InputValue type represents field and directive arguments as well as the inputFields of an input object.

Fields

  • name must return a String
  • description may return a String or {null}
  • type must return a __Type that represents the type this input value expects.
  • defaultValue may return a String encoding (using the GraphQL language) of the default value used by this input value in the condition a value is not provided at runtime. If this input value has no default value, returns {null}.

The __EnumValue Type

The __EnumValue type represents one of possible values of an enum.

Fields

  • name must return a String
  • description may return a String or {null}
  • isDeprecated returns {true} if this field should no longer be used, otherwise {false}.
  • deprecationReason optionally provides a reason why this field is deprecated.

The __Directive Type

The __Directive type represents a Directive that a server supports.

Fields

  • name must return a String
  • description may return a String or {null}
  • locations returns a List of __DirectiveLocation representing the valid locations this directive may be placed.
  • args returns a List of __InputValue representing the arguments this directive accepts.