Schema Definition Language
Defining Schema
in IDL/SDL can greatly speed up and simplify code base.
Load schema from SDL
SchemaBuilder
class has an extension method for loading types from SDL strings
or GraphQL documents.
Schema
[Fact]
public void Parse_Document_as_Schema()
{
/* Given */
var idl = @"
type Query {
}
type Mutation {
}
type Subscription {
}
schema {
query: Query
mutation: Mutation
subscription: Subscription
}";
var document = Parser.ParseTypeSystemDocument(idl);
/* When */
var actual = new SchemaBuilder().Sdl(document)
.Build();
/* Then */
Assert.NotNull(actual);
Assert.NotNull(actual.Query);
Assert.NotNull(actual.Mutation);
Assert.NotNull(actual.Subscription);
}
Types
[Fact]
public void Parse_Document_with_types()
{
/* Given */
var idl = @"
scalar JediPowerLevel
scalar JediTrickLevel
enum Episode { NEWHOPE, EMPIRE, JEDI }
interface Character {
id: String!
name: String
friends: [Character]
appearsIn: [Episode]
}
type Human implements Character {
id: String!
name: String
friends: [Character]
appearsIn: [Episode]
homePlanet: String
}
type Droid implements Character {
id: String!
name: String
friends: [Character]
appearsIn: [Episode]
primaryFunction: String
}
input JediPowerInput {
power: String
level: JediPowerLevel
}
type Query {
}
schema {
query: Query
}
";
var builder = new SchemaBuilder()
.Sdl(idl);
builder.TryGetType<ScalarType>("JediPowerLevel", out var jediPowerLevel);
builder.TryGetType<ScalarType>("JediTrickLevel", out var jediTrickLevel);
builder.Include("JediPowerLevel", new IntConverter())
.Include("JediTrickLevel", new IntConverter());
/* When */
var schema = builder.Build();
var actual = schema.QueryTypes<INamedType>();
/* Then */
Assert.Contains(actual, type => type.Name == "Episode" && type is EnumType);
Assert.Contains(actual, type => type.Name == "Character" && type is InterfaceType);
Assert.Contains(actual, type => type.Name == "Human" && type is ObjectType);
Assert.Contains(actual, type => type.Name == "Droid" && type is ObjectType);
Assert.Contains(actual, type => type.Name == "JediPowerInput" && type is InputObjectType);
Assert.Contains(actual, type => type.Name == "JediPowerLevel" && type.GetType() == typeof(ScalarType));
Assert.Contains(actual, type => type.Name == "JediTrickLevel" && type.GetType() == typeof(ScalarType));
var jediPowerInput = (InputObjectType) actual.Single(t => t.Name == "JediPowerInput");
var level = schema.GetInputField(jediPowerInput.Name, "level");
Assert.Equal(jediPowerLevel, level.Type);
}
Custom scalars
[Fact]
public void Parse_custom_scalar()
{
/* Given */
var idl = @"
scalar Url
type Query {
}
schema {
query: Query
}
";
var builder = new SchemaBuilder()
.Sdl(idl);
/* When */
builder.TryGetType<ScalarType>("Url", out var actual);
/* Then */
Assert.Equal("Url", actual.Name);
}
Types can be extended
[Fact]
public void Parse_ObjectType_with_extension()
{
/* Given */
var idl = @"
extend type Human {
second: Boolean
}
type Human {
first: Int
}
type Query {
}
schema {
query: Query
}
";
var document = Parser.ParseTypeSystemDocument(idl);
/* When */
var actual = new SchemaBuilder().Sdl(document).Build();
/* Then */
var human = actual.GetNamedType<ObjectType>("Human");
var humanFields = actual.GetFields(human.Name);
Assert.NotNull(human);
Assert.Equal("Human", human.Name);
Assert.Single(humanFields, f => f.Key == "first");
Assert.Single(humanFields, f => f.Key == "second");
}