Common options
Tanka provides SignalR hub and websockets server. Both of these use same underlying services for query execution.
Add required common services
Add services required for executing GraphQL queries, mutations
and subscriptions. Main service added is IQueryStreamService
which handles the plumping of execution.
[Fact]
public void AddTankaGraphQL()
{
/* When */
Services.AddTankaGraphQL()
.ConfigureSchema(() => default);
/* Then */
var provider = Services.BuildServiceProvider();
// Options is added by the AddTankaGraphQL
Assert.NotNull(provider.GetService<IOptions<ServerOptions>>());
// Query stream service is added by AddTankaGraphQL
Assert.NotNull(provider.GetService<IQueryStreamService>());
}
Configure schema
Configure ISchema
for execution by providing a factory function (can be async)
used to get the schema for execution.
Simple without dependencies
[Fact]
public async Task Configure_Schema()
{
/* Given */
var schema = Substitute.For<ISchema>();
/* When */
Services.AddTankaGraphQL()
// simple factory function for setting up the schema
.ConfigureSchema(() => new ValueTask<ISchema>(schema));
/* Then */
var provider = Services.BuildServiceProvider();
var options = provider.GetService<IOptions<ServerOptions>>().Value;
var actual = await options.GetSchema(null);
Assert.Same(schema, actual);
}
Overloads are provided for providing a function with dependencies resolved from services.
[Fact]
public async Task Configure_Schema_with_dependency()
{
/* Given */
var schema = Substitute.For<ISchema>();
/* When */
Services.AddTankaGraphQL()
// factory function with one dependency resolved from service provider
.ConfigureSchema<IMemoryCache>(async cache =>
await cache.GetOrCreateAsync("schema", entry => Task.FromResult(schema)));
/* Then */
var provider = Services.BuildServiceProvider();
var options = provider.GetService<IOptions<ServerOptions>>().Value;
var actual = await options.GetSchema(null);
Assert.Same(schema, actual);
}
Configure rules
Configure validation rules for execution. Note that by default all rules specified in the specification are included.
Add MaxCost validation rule
[Fact]
public void Configure_Rules()
{
/* Given */
var schema = Substitute.For<ISchema>();
var maxCost = CostAnalyzer.MaxCost(100);
/* When */
Services.AddTankaGraphQL()
.ConfigureSchema(() => new ValueTask<ISchema>(schema))
// rules factory function with the default rules as the parameter
.ConfigureRules(rules => rules.Concat(new []
{
// append max query cost validation rule
maxCost
}).ToArray());
/* Then */
var provider = Services.BuildServiceProvider();
var options = provider.GetService<IOptions<ServerOptions>>().Value;
var actual = options.ValidationRules;
Assert.Contains(actual, rule => rule == maxCost);
}
Remove all rules
[Fact]
public void Configure_Rules_remove_all()
{
/* Given */
var schema = Substitute.For<ISchema>();
/* When */
Services.AddTankaGraphQL()
.ConfigureSchema(() => new ValueTask<ISchema>(schema))
// rules factory function with the default rules as the parameter
.ConfigureRules(rules => new CombineRule[0]);
/* Then */
var provider = Services.BuildServiceProvider();
var options = provider.GetService<IOptions<ServerOptions>>().Value;
var actual = options.ValidationRules;
Assert.Empty(actual);
}
With up to three dependencies resolved from service provider
[Fact]
public void Configure_Rules_with_dependency()
{
/* Given */
var schema = Substitute.For<ISchema>();
/* When */
Services.AddTankaGraphQL()
.ConfigureSchema(() => new ValueTask<ISchema>(schema))
// rules factory function with default rules and dependency resolved from service provider
.ConfigureRules<ILogger<ServerBuilderUsageFacts>>((rules, logger) => new CombineRule[0]);
/* Then */
var provider = Services.BuildServiceProvider();
var options = provider.GetService<IOptions<ServerOptions>>().Value;
var actual = options.ValidationRules;
Assert.Empty(actual);
}
Add extensions
Add Apollo tracing extension
[Fact]
public void Add_Extension()
{
/* When */
Services.AddTankaGraphQL()
.ConfigureSchema(() => default)
// add trace execution extension
.AddExtension<TraceExtension>();
/* Then */
var provider = Services.BuildServiceProvider();
var executorExtensions = provider.GetService<IEnumerable<IExecutorExtension>>();
Assert.Contains(executorExtensions, extension => extension is TraceExtension);
}