Schema Introspection
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.Interface("Interface", out var interface1,
"Description")
.Connections(connect => connect
.Field(interface1, ScalarFieldName, ScalarType.Int));
builder.Object(ObjectTypeName, out var type1,
"Description",
new[] {interface1})
.Connections(connect => connect
.Field(type1, ScalarFieldName, ScalarType.NonNullInt,
"Description",
args: args => args.Arg("arg1", ScalarType.Float, 1d, "Description")));
builder.Object($"{ObjectTypeName}2", out var type2,
"Description")
.Connections(connect => connect
.Field(type2, ScalarFieldName, new List(ScalarType.Int)));
var union = new UnionType(
"Union",
new[] {type1, type2},
"Description");
builder.Include(union);
var enum1 = new EnumType(
"Enum",
new EnumValues
{
{"value1", "Description"},
{"value2", "Description", null, "Deprecated"}
},
"Description");
builder.Include(enum1);
builder.InputObject("InputObject", out var inputObject,
"Description")
.Connections(connect => connect
.InputField(inputObject, "field1", ScalarType.Boolean, true, "Description"));
builder.Query(out var query)
.Connections(connect => connect
.Field(query, "object", type1)
.Field(query, "union", union)
.Field(query, "enum", enum1)
.Field(query, "listOfObjects", new List(type2))
.Field(query, "nonNullObject", new NonNull(type1))
.Field(query, "inputObjectArg", ScalarType.NonNullBoolean,
args: args => args.Arg("arg1", inputObject, default, "With inputObject arg")));
builder.Mutation(out var mutation);
builder.Subscription(out var subscription);
var sourceSchema = builder.Build();
_introspectionSchema = Introspect.Schema(sourceSchema);
}
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"": {
""interfaces"": [
{
""name"": ""Interface""
}
],
""fields"": [
{
""name"": ""int""
}
],
""kind"": ""OBJECT"",
""description"": ""Description"",
""name"": ""Object""
}
}
}");
}
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"",
""description"": ""Description"",
""possibleTypes"": [
{
""name"": ""Object""
},
{
""name"": ""Object2""
}
],
""name"": ""Union""
}
}
}");
}
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 */
//todo(pekka): separate enumValues testing to own test
var query = @"{
__type(name: ""Enum"") {
kind
name
description
enumValues {
name
description
isDeprecated
deprecationReason
}
}
}";
/* When */
var result = await QueryAsync(query);
/* Then */
result.ShouldMatchJson(
@"{
""data"": {
""__type"": {
""description"": ""Description"",
""name"": ""Enum"",
""enumValues"": [
{
""description"": ""Description"",
""name"": ""VALUE1"",
""isDeprecated"": false,
""deprecationReason"": null
}
],
""kind"": ""ENUM""
}
}
}");
}
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"": {
""name"": ""InputObject"",
""description"": ""Description"",
""kind"": ""INPUT_OBJECT""
}
}
}");
}