Apply directives
Directives are annotations for your GraphQL schema or operations.
See also
Tanka GraphQL provides support for execution and schema directives:
- Execution directives: Include and Skip
- Schema directives
Currrently schema directives are only supported on fields of object types
Schema directives
Schema directives can be used to modify field for example by modifying the resolver of the field.
[Fact]
public async Task Part3_ApplyDirectives_on_Object_fields()
{
// Create builder, load sdl with our types
// and bind the resolvers
var builder = new SchemaBuilder()
.Sdl(@"
directive @duplicate on FIELD_DEFINITION
type Query {
name: String @duplicate
}
")
.GetQuery(out var query)
.UseResolversAndSubscribers(
new ObjectTypeMap
{
{
query.Name, new FieldResolversMap
{
{
"name", context =>
{
var result = Resolve.As("Test");
return new ValueTask<IResolverResult>(result);
}
}
}
}
});
// Apply directives to schema by providing a visitor which
// will transform the fields with the directive into new
// fields with the directive logic. Note that the original
// field will be replaced.
builder.ApplyDirectives(new Dictionary<string, CreateDirectiveVisitor>()
{
["duplicate"] = _ => new DirectiveVisitor()
{
// Visitor will visit field definitions
FieldDefinition = (directive, fieldDefinition) =>
{
// We will create new field definition with
// new resolver. New resolver will execute the
// original resolver, duplicate value and return it
return fieldDefinition
.WithResolver(resolver =>
resolver.Use(async (context, next) =>
{
// We need to first call the original resolver to
// get the initial value
var result = await next(context);
// for simplicity we expect value to be string
var initialValue = result.Value.ToString();
// return new value
return Resolve.As(initialValue + initialValue);
}).Run(fieldDefinition.Resolver));
}
}
});
// Build schema
var schema = builder.Build();
// Get resolver for Query.name field
var nameResolver = schema.GetResolver(schema.Query.Name, "name");
// Execute the resolver. This is normally handled by the executor.
var nameValue = await nameResolver(null);
Assert.Equal("TestTest", nameValue.Value);
}