Schema Introspection

Specification

Introspecting a schema produces an executable schema. Queries can be executed against this schema normally.

Create and introspect a schema


    public IntrospectSchemaFacts()
    {
        var builder = new SchemaBuilder();
        builder.Add(@"

""""""Description""""""
interface Interface 
{
    int: Int    
}

""""""Description""""""
type Object implements Interface
{
    int: Int
    """"""Description""""""
    nonNullInt(arg1: Float = 1): Int!
}

type Object2 
{
    int: [Int]
}

""""""Description""""""
union Union = Object | Object2

""""""Description""""""
enum Enum {
    """"""Description""""""
    VALUE1
    
    """"""Description""""""
    VALUE2 @deprecated(reason: ""reason"")
}

""""""Description""""""
input InputObject 
{
    """"""Description""""""
    field1: Boolean = true
}

type Query {
    object: Object
    union: Union
    enum: Enum
    listOfObjects: [Object2]
    nonNullObject: Object1!

    """"""Description""""""
    inputObjectArg(arg1: InputObject): Boolean!
}

type Mutation {}
type Subscription {}
");


        _introspectionSchema = builder.Build(new SchemaBuildOptions()
        {
            IncludeIntrospection = true // note: on by default
        }).Result;
    }

Combination of the source schema and the introspection schema can be used to provide the normal executable schema with introspection support.

Type Kinds

Scalar


    [Fact]
    public async Task Type_ScalarType()
    {
        /* Given */
        var query = @"{ 
                            __type(name: ""Int"") {
                                kind
                                name
                                description
                            }
                        }";

        /* When */
        var result = await QueryAsync(query);

        /* Then */
        result.ShouldMatchJson(
            @"{
                  ""data"": {
                    ""__type"": {
                      ""name"": ""Int"",
                      ""description"": ""The `Int` scalar type represents non-fractional signed whole numeric values"",
                      ""kind"": ""SCALAR""
                    }
                  }
                }");
    }

Object type


    [Fact]
    public async Task Type_ObjectType()
    {
        /* Given */
        var query = @"{ 
                            __type(name: ""Object"") {
                                kind
                                name
                                description
                                fields { name }
                                interfaces { name }
                            }
                        }";

        /* When */
        var result = await QueryAsync(query);

        /* Then */
        result.ShouldMatchJson(
            @"{
  ""data"": {
    ""__type"": {
      ""kind"": ""OBJECT"",
      ""name"": ""Object"",
      ""description"": ""Description"",
      ""fields"": [
        {
          ""name"": ""int""
        },
        {
          ""name"": ""nonNullInt""
        }
      ],
      ""interfaces"": [
        {
          ""name"": ""Interface""
        }
      ]
    }
  },
  ""extensions"": null,
  ""errors"": null
}");
    }

Union type


    [Fact]
    public async Task Type_UnionType()
    {
        /* Given */
        var query = @"{ 
                            __type(name: ""Union"") {
                                kind
                                name
                                description
                                possibleTypes { name }
                            }
                        }";

        /* When */
        var result = await QueryAsync(query);

        /* Then */
        result.ShouldMatchJson(
            @"{
  ""data"": {
    ""__type"": {
      ""kind"": ""UNION"",
      ""name"": ""Union"",
      ""description"": ""Description"",
      ""possibleTypes"": [
        {
          ""name"": ""Object""
        },
        {
          ""name"": ""Object2""
        }
      ]
    }
  },
  ""extensions"": null,
  ""errors"": null
}");
    }

Interface type


    [Fact]
    public async Task Type_InterfaceType()
    {
        /* Given */
        var query = @"{ 
                            __type(name: ""Interface"") {
                                kind
                                name
                                description
                                fields { name }
                                possibleTypes { name }
                            }
                        }";

        /* When */
        var result = await QueryAsync(query);

        /* Then */
        result.ShouldMatchJson(
            @"{
                  ""data"": {
                    ""__type"": {
                      ""possibleTypes"": [
                        {
                          ""name"": ""Object""
                        }
                      ],
                      ""name"": ""Interface"",
                      ""kind"": ""INTERFACE"",
                      ""fields"": [
                        {
                          ""name"": ""int""
                        }
                      ],
                      ""description"": ""Description""
                    }
                  }
                }");
    }

Enum type


    [Fact]
    public async Task Type_EnumType()
    {
        /* Given */
        var query = @"{ 
                            __type(name: ""Enum"") {
                                kind
                                name
                                description
                                enumValues { 
                                  name
                                  description
                                  isDeprecated
                                  deprecationReason
                                }
                            }
                        }";

        /* When */
        var result = await QueryAsync(query);

        /* Then */
        result.ShouldMatchJson(
            @"{
  ""data"": {
    ""__type"": {
      ""kind"": ""ENUM"",
      ""name"": ""Enum"",
      ""description"": ""Description"",
      ""enumValues"": [
        {
          ""name"": ""VALUE1"",
          ""description"": ""Description"",
          ""isDeprecated"": false,
          ""deprecationReason"": null
        }
      ]
    }
  },
  ""extensions"": null,
  ""errors"": null
}");
    }

Input object


    [Fact]
    public async Task Type_InputObjectType()
    {
        /* Given */
        var query = @"{ 
                            __type(name: ""InputObject"") {
                                kind
                                name
                                description
                            }
                        }";

        /* When */
        var result = await QueryAsync(query);

        /* Then */
        result.ShouldMatchJson(
            @"{
  ""data"": {
    ""__type"": {
      ""kind"": ""INPUT_OBJECT"",
      ""name"": ""InputObject"",
      ""description"": ""Description""
    }
  },
  ""extensions"": null,
  ""errors"": null
}");
    }