Table of Contents

Introspection

Introspection is the combination of fields, objects, and enums that exist to describe everything your schema has. Several other libraries use the introspection of a schema to generate more code or to provide autocompletion, for example.

Enabling

There are three ways to enable introspection:

  1. Using the enable_introspection setting;
  2. Using the schema’s configuration;
  3. Or calling enable_introspection! in your schema.
# app/graphql/app_schema.rb
config.enable_introspection = !Rails.env.production?

Dangerous You should always disable introspection in a production environment. Otherwise, malicious users can exploit it and misuse your application.

The Query

This is the common query used by libraries and other services based on GraphQL to collect all the information they need:

Introspection Query
query IntrospectionQuery {
  __schema {
    queryType { name }
    mutationType { name }
    subscriptionType { name }
    types {
      ...FullType
    }
    directives {
      name
      description
      locations
      args {
        ...InputValue
      }
      isRepeatable
    }
  }
}

fragment FullType on __Type {
  kind
  name
  description
  specifiedByURL
  fields(includeDeprecated: true) {
    name
    description
    args {
      ...InputValue
    }
    type {
      ...TypeRef
    }
    isDeprecated
    deprecationReason
  }
  inputFields {
    ...InputValue
  }
  interfaces {
    ...TypeRef
  }
  enumValues(includeDeprecated: true) {
    name
    description
    isDeprecated
    deprecationReason
  }
  possibleTypes {
    ...TypeRef
  }
}

fragment InputValue on __InputValue {
  name
  description
  type { ...TypeRef }
  defaultValue
}

fragment TypeRef on __Type {
  kind
  name
  ofType {
    kind
    name
    ofType {
      kind
      name
      ofType {
        kind
        name
        ofType {
          kind
          name
          ofType {
            kind
            name
            ofType {
              kind
              name
              ofType {
                kind
                name
              }
            }
          }
        }
      }
    }
  }
}

The Components

To deliver such result, several elements are added to your schema.

Fields

These fields are added to the query_fields of your schema.

__schema: __Schema!

It resolves to the schema of the request, and returns a __Schema type.

__type(name: String!): __Type

It looks for a type with the given name. If it finds one from the Type Map, it returns a __Type type.

Objects

These objects (and respective fields) are added to your schema.

__Directive

Displays the information about a directive.

name
String! - Its GraphQL name
description
String - The description
locations
[__DirectiveLocation!]! - The locations where the directive can be applied
args
[__InputValue!]! - The list of arguments accepted by the directive
isRepeatable
Boolean! - Indicates if the directive can be repeated

__EnumValue

Displays the information about an enum value.

name
String! - The GraphQL name
description
String - The description
isDeprecated
Boolean! - indicates if the value is deprecated
deprecationReason
String - The reason added to the deprecated directive - if any

__Field

Displays the information about an output field.

name
String! - The GraphQL name
description
String - The description
args
[__InputValue!]! - The list of arguments accepted by the field
type
__Type! - The return type
isDeprecated
Boolean! - Indicates if the field is deprecated
deprecationReason
String - The reason added to the deprecated directive, if any

__InputValue

Displays the information about an argument or input field.

name
String! - The GraphQL name
description
String - The description
type
__Type! - The accepted type
defaultValue
String - The default value formatted as JSON string

__Schema

Displays the information about a schema.

types
[__Type!]! - All its known types
queryType
__Type! - The object with the query fields
mutationType
__Type - The object with the mutation fields
subscriptionType
__Type - The object with the subscription fields
directives
[__Directive!]! - All its known directives

__Type

Displays the information about a type (enums, inputs, interfaces, objects, scalars, and unions).

kind
__TypeKind! - Which kind of type
name
String! - The GraphQL name
description
String - The description
specifiedByURL
String - The specification url
(only for scalars)
fields
[__Field!] - The list of output fields
(only for objects and interfaces)
interfaces
[__Type!] - The list of implemented interfaces
(only for objects)
possibleTypes
[__Type!] - The possible object types
(only for interfaces and unions)
enumValues
[__EnumValue!] - The list of enum values
(only for enums)
inputFields
[__InputValue!] - The list of input fields
(only for inputs)
ofType
__Type - The underlying type

List

A simple object to represent that a type is a list of another type, as in [String].

kind
__TypeKind! - LIST
name
String! - List
ofType
__Type - The underlying type

Non-Null

A simple object to represent that a type won’t be null, as in String!.

kind
__TypeKind! - NON_NULL
name
String! - Non-Null
ofType
__Type - The underlying type

These last two objects are not added to the Type Map because their sole purpose is to allow the ofType navigation.

Enums

These enums (and respective values) are added to your schema.

__DirectiveLocation

The valid locations that a directive may be placed.

QUERY, MUTATION, SUBSCRIPTION, FIELD, FRAGMENT_DEFINITION, FRAGMENT_SPREAD, INLINE_FRAGMENT, SCHEMA, SCALAR, OBJECT, FIELD_DEFINITION, ARGUMENT_DEFINITION, INTERFACE, UNION, ENUM, ENUM_VALUE, INPUT_OBJECT, INPUT_FIELD_DEFINITION

__TypeKind

The fundamental unit of any GraphQL Schema is the type. This enum enlist all the valid base types.

SCALAR, OBJECT, INTERFACE, UNION, ENUM, INPUT_OBJECT, LIST, NON_NULL

Schema Example

Here is an example of a GraphQL schema that only includes the introspection elements:

Introspection Schema
schema {
  query: _Query
}

scalar Boolean

scalar Float

scalar ID

scalar Int

scalar String

enum __DirectiveLocation {
  QUERY
  MUTATION
  SUBSCRIPTION
  FIELD
  FRAGMENT_DEFINITION
  FRAGMENT_SPREAD
  INLINE_FRAGMENT
  SCHEMA
  SCALAR
  OBJECT
  FIELD_DEFINITION
  ARGUMENT_DEFINITION
  INTERFACE
  UNION
  ENUM
  ENUM_VALUE
  INPUT_OBJECT
  INPUT_FIELD_DEFINITION
}

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

type _Query {
  __schema: __Schema!
  __type(name: String!): __Type
}

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

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

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

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

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

type __Type {
  description: String
  enumValues(includeDeprecated: Boolean = false): [__EnumValue!]
  fields(includeDeprecated: Boolean = false): [__Field!]
  inputFields: [__InputValue!]
  interfaces: [__Type!]
  kind: __TypeKind!
  name: String
  ofType: __Type
  possibleTypes: [__Type!]
  specifiedByURL: String
}

directive @deprecated(reason: String) on FIELD_DEFINITION | ENUM_VALUE

directive @include(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT

directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT

directive @specifiedBy(url: String!) on SCALAR

You can get a similar result from your to_gql output.