Schema
Schema is defined by ISchema
-interface.
using System;
using System.Collections.Generic;
using System.Linq;
using Tanka.GraphQL.TypeSystem.ValueSerialization;
using Tanka.GraphQL.ValueResolution;
namespace Tanka.GraphQL.TypeSystem
{
public interface ISchema : IHasDirectives, IType
{
ObjectType? Subscription { get; }
ObjectType Query { get; }
ObjectType? Mutation { get; }
INamedType GetNamedType(string name);
IField GetField(string type, string name);
IEnumerable<KeyValuePair<string, IField>> GetFields(string type);
IQueryable<T> QueryTypes<T>(Predicate<T>? filter = null) where T : INamedType;
DirectiveType GetDirectiveType(string name);
IQueryable<DirectiveType> QueryDirectiveTypes(Predicate<DirectiveType> filter = null);
IEnumerable<KeyValuePair<string, InputObjectField>> GetInputFields(string type);
InputObjectField GetInputField(string type, string name);
IEnumerable<ObjectType> GetPossibleTypes(IAbstractType abstractType);
Resolver GetResolver(string type, string fieldName);
Subscriber GetSubscriber(string type, string fieldName);
IValueConverter GetValueConverter(string type);
}
}
Rarely accessing the actual implemention class
GraphSchema
is required
Schema is immutable and cannot be changed directly once created. To create Schema
instance you need to provide query
root object at minimum. Optionally mutation
and subscription
roots can be also provided.
Basics
Built by SchemaBuilder
public SchemaFacts()
{
Schema = new SchemaBuilder()
.InputObject("input", out var input)
.Connections(connect => connect
.InputField(input, "id", ScalarType.ID))
.Query(out var query)
.Connections(connect => connect
.Field(query, "name", ScalarType.String))
.Build();
}
Query root is ObjectType
[Fact]
public void Roots_Query()
{
/* Given */
/* When */
/* Then */
Assert.NotNull(Schema.Query);
Assert.IsType<ObjectType>(Schema.Query);
}
Mutation is optional
[Fact]
public void Roots_Mutation()
{
/* Given */
/* When */
/* Then */
Assert.Null(Schema.Mutation);
}
Subscription is optional
[Fact]
public void Roots_Subscription()
{
/* Given */
/* When */
/* Then */
Assert.Null(Schema.Subscription);
}
Querying types
Query named types
[Fact]
public void GetNamedType()
{
/* Given */
var namedTypeName = Schema.Query.Name;
/* When */
var namedType = Schema.GetNamedType(namedTypeName);
/* Then */
Assert.NotNull(namedType);
Assert.IsAssignableFrom<INamedType>(namedType);
}
[Fact]
public void QueryNamedTypes()
{
/* Given */
bool TypesWithoutDescription(ObjectType type)
{
return string.IsNullOrEmpty(type.Description);
}
/* When */
var undocumentedTypes = Schema.QueryTypes<ObjectType>(TypesWithoutDescription);
/* Then */
Assert.NotNull(undocumentedTypes);
Assert.Single(undocumentedTypes, type => type.Name == "Query");
}
Query directives
[Fact]
public void GetDirective()
{
/* Given */
var directiveTypeName = DirectiveType.Include.Name;
/* When */
var directiveType = Schema.GetDirectiveType(directiveTypeName);
/* Then */
Assert.NotNull(directiveType);
Assert.IsType<DirectiveType>(directiveType);
}
[Fact]
public void QueryDirectives()
{
/* Given */
bool AppliesToField(DirectiveType type)
{
return type.Locations.Contains(DirectiveLocation.FIELD);
}
/* When */
var directives = Schema.QueryDirectiveTypes(AppliesToField)
.ToList();
/* Then */
foreach (var directiveType in directives)
Assert.Contains(DirectiveLocation.FIELD, directiveType.Locations);
}
Query fields
[Fact]
public void GetField()
{
/* Given */
var namedTypeName = Schema.Query.Name;
/* When */
var field = Schema.GetField(namedTypeName, "name");
/* Then */
Assert.NotNull(field);
Assert.Same(ScalarType.String, field.Type);
}
[Fact]
public void GetFields()
{
/* Given */
var namedTypeName = Schema.Query.Name;
/* When */
var fields = Schema.GetFields(namedTypeName);
/* Then */
Assert.Single(
fields,
kv => kv.Key == "name" && (ScalarType) kv.Value.Type == ScalarType.String);
}
Query input fields
[Fact]
public void GetInputField()
{
/* Given */
var inputTypeName = "input";
/* When */
var field = Schema.GetInputField(inputTypeName, "id");
/* Then */
Assert.NotNull(field);
Assert.Same(ScalarType.ID, field.Type);
}
[Fact]
public void GetInputFields()
{
/* Given */
var inputTypeName = "input";
/* When */
var fields = Schema.GetInputFields(inputTypeName);
/* Then */
Assert.Single(
fields,
kv => kv.Key == "id" && (ScalarType) kv.Value.Type == ScalarType.ID);
}
Defaults
By default Skip and Include directives are included
[Fact]
public void Included_directives()
{
/* Given */
/* When */
var directives = Schema.QueryDirectiveTypes();
/* Then */
Assert.Single(directives, DirectiveType.Include);
Assert.Single(directives, DirectiveType.Skip);
}
By default all standard ScalarType
s are included
[Fact]
public void Included_scalars()
{
/* Given */
/* When */
var scalars = Schema.QueryTypes<ScalarType>()
.ToList();
/* Then */
foreach (var scalar in ScalarType.Standard)
{
Assert.Contains(scalar.Type, scalars);
}
}