Module: GraphQL::Introspection

Defined in:
lib/graphql/introspection.rb,
lib/graphql/introspection/schema_field.rb,
lib/graphql/introspection/typename_field.rb,
lib/graphql/introspection/type_by_name_field.rb

Defined Under Namespace

Classes: SchemaField, TypeByNameField, TypenameField

Constant Summary collapse

TypeType =
GraphQL::ObjectType.define do
  name "__Type"
  description "A type in the GraphQL schema"

  field :name, types.String,  "The name of this type"
  field :description, types.String, "What this type represents"

  field :kind do
    type !GraphQL::Introspection::TypeKindEnum
    description "The kind of this type"
    resolve -> (target, a, c) { target.kind.name }
  end

  field :fields,          field: GraphQL::Introspection::FieldsField
  field :ofType,          field: GraphQL::Introspection::OfTypeField
  field :inputFields,     field: GraphQL::Introspection::InputFieldsField
  field :possibleTypes,   field: GraphQL::Introspection::PossibleTypesField
  field :enumValues,      field: GraphQL::Introspection::EnumValuesField
  field :interfaces,      field: GraphQL::Introspection::InterfacesField
end
FieldType =
GraphQL::ObjectType.define do
  name "__Field"
  description "Field on a GraphQL type"
  field :name, !types.String, "The name for accessing this field"
  field :description, types.String, "The description of this field"
  field :type, !GraphQL::Introspection::TypeType, "The return type of this field"
  field :isDeprecated, !types.Boolean, "Is this field deprecated?" do
    resolve -> (obj, a, c) { !!obj.deprecation_reason }
  end
  field :args, GraphQL::Introspection::ArgumentsField
  field :deprecationReason, types.String,  "Why this field was deprecated", property: :deprecation_reason
end
SchemaType =
GraphQL::ObjectType.define do
  name "__Schema"
  description "A GraphQL schema"

  field :types, !types[!GraphQL::Introspection::TypeType], "Types in this schema" do
    resolve -> (obj, arg, ctx) { obj.types.values }
  end

  field :directives, !types[!GraphQL::Introspection::DirectiveType], "Directives in this schema" do
    resolve -> (obj, arg, ctx) { obj.directives.values }
  end

  field :queryType, !GraphQL::Introspection::TypeType, "The query root of this schema" do
    resolve -> (obj, arg, ctx) { obj.query }
  end

  field :mutationType, GraphQL::Introspection::TypeType, "The mutation root of this schema" do
    resolve -> (obj, arg, ctx) { obj.mutation }
  end

  field :subscriptionType, GraphQL::Introspection::TypeType, "The subscription root of this schema" do
    resolve -> (obj, arg, ctx) { obj.subscription }
  end
end
FieldsField =
GraphQL::Field.define do
  description "List of fields on this object"
  type -> { types[!GraphQL::Introspection::FieldType] }
  argument :includeDeprecated, GraphQL::BOOLEAN_TYPE, default_value: false
  resolve -> (object, arguments, context) {
    return nil if !object.kind.fields?
    fields = object.all_fields
    if !arguments["includeDeprecated"]
      fields = fields.select {|f| !f.deprecation_reason }
    end
    fields.sort_by(&:name)
  }
end
OfTypeField =
GraphQL::Field.define do
  name "ofType"
  description "The modified type of this type"
  type -> { GraphQL::Introspection::TypeType }
  resolve -> (obj, args, ctx) { obj.kind.wraps? ? obj.of_type : nil }
end
DirectiveType =
GraphQL::ObjectType.define do
  name "__Directive"
  description "A query directive in this schema"
  field :name, !types.String, "The name of this directive"
  field :description, types.String, "The description for this type"
  field :args, field: GraphQL::Introspection::ArgumentsField
  field :locations, !types[!GraphQL::Introspection::DirectiveLocationEnum]
  field :onOperation, !types.Boolean, "Does this directive apply to operations?", deprecation_reason: "Moved to 'locations' field", property: :on_operation?
  field :onFragment, !types.Boolean, "Does this directive apply to fragments?", deprecation_reason: "Moved to 'locations' field", property: :on_fragment?
  field :onField, !types.Boolean, "Does this directive apply to fields?", deprecation_reason: "Moved to 'locations' field", property: :on_field?
end
TypeKindEnum =
GraphQL::EnumType.define do
  name "__TypeKind"
  description "The kinds of types in this GraphQL system"
  GraphQL::TypeKinds::KIND_NAMES.each do |kind_name|
    value(kind_name)
  end
end
ArgumentsField =
GraphQL::Field.define do
  description "Arguments allowed to this object"
  type !GraphQL::ListType.new(of_type: !GraphQL::Introspection::InputValueType)
  resolve -> (target, a, c) { target.arguments.values }
end
EnumValueType =
GraphQL::ObjectType.define do
  name "__EnumValue"
  description "A possible value for an Enum"
  field :name, !types.String
  field :description, types.String
  field :deprecationReason, types.String, property: :deprecation_reason
  field :isDeprecated, !types.Boolean do
    resolve -> (obj, a, c) { !!obj.deprecation_reason }
  end
end
InputValueType =
GraphQL::ObjectType.define do
  name "__InputValue"
  description "An input for a field or InputObject"
  field :name, !types.String, "The key for this value"
  field :description, types.String, "What this value is used for"
  field :type, !GraphQL::Introspection::TypeType, "The expected type for this value"
  field :defaultValue, types.String, "The value applied if no other value is provided" do
    resolve -> (obj, args, ctx) {
      value = obj.default_value
      if value.is_a?(String)
        "\"#{value}\""
      else
        value
      end
    }
  end
end
InterfacesField =
GraphQL::Field.define do
  description "Interfaces which this object implements"
  type -> { types[!GraphQL::Introspection::TypeType] }
  resolve -> (target, a, c) { target.kind.object? ? target.interfaces : nil }
end
EnumValuesField =
GraphQL::Field.define do
  description "Values for this enum"
  type types[!GraphQL::Introspection::EnumValueType]
  argument :includeDeprecated, types.Boolean, default_value: false
  resolve -> (object, arguments, context) do
    return nil if !object.kind.enum?
    fields = object.values.values
    if !arguments["includeDeprecated"]
      fields = fields.select {|f| !f.deprecation_reason }
    end
    fields
  end
end
InputFieldsField =
GraphQL::Field.define do
  name "inputFields"
  description "fields on this input object"
  type types[!GraphQL::Introspection::InputValueType]
  resolve -> (target, a, c) {
    if target.kind.input_object?
      target.input_fields.values
    else
      nil
    end
  }
end
INTROSPECTION_QUERY =

The introspection query to end all introspection queries, copied from github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js

"
query IntrospectionQuery {
  __schema {
    queryType { name }
    mutationType { name }
    subscriptionType { name }
    types {
      ...FullType
    }
    directives {
      name
      description
      locations
      args {
        ...InputValue
      }
    }
  }
}
fragment FullType on __Type {
  kind
  name
  description
  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
      }
    }
  }
}
"
PossibleTypesField =
GraphQL::Field.define do
  description "Types which compose this Union or Interface"
  type -> { types[!GraphQL::Introspection::TypeType] }
  resolve -> (target, args, ctx) {
    if target.kind.resolves?
      ctx.schema.possible_types(target)
    else
      nil
    end
  }
end
DirectiveLocationEnum =
GraphQL::EnumType.define do
  name "__DirectiveLocation"
  description "Parts of the query where a directive may be located"

  GraphQL::Directive::LOCATIONS.each do |location|
    value(location.to_s, value: location)
  end
end