Enabling a GraphQL endpoint in your ASP.NET Core application is quite easy thanks to the GraphQL.Server.Transports.AspNetCore NuGet package.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public void ConfigureServices(IServiceCollection services) | |
{ | |
services | |
.AddGraphQL(new GraphQLOptions() { ExposeExceptions = true, EnableMetrics=false }) | |
.AddDataLoader(); | |
// .AddGraphQLAuthorization(); | |
services.AddSingleton<GraphQL.IDependencyResolver>( | |
c => new FuncDependencyResolver(type => c.GetRequiredService(type))); | |
} |
One of the nice features of GraphQL is that you can extend your resolvers using custom middleware. In the GraphQL.NET documentation they refer to the FieldsMiddleware property to register this extra middleware:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
schema.Execute(_ => | |
{ | |
_.Query = "..."; | |
_.FieldMiddleware.Use<InstrumentFieldsMiddleware>(); | |
}); |
Unfortunately when using the GraphQL.Server package you only have an GraphQLOptions object but the only thing you can do is set a SetFieldMiddleware flag:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class GraphQLOptions | |
{ | |
public GraphQLOptions(); | |
public ComplexityConfiguration ComplexityConfiguration { get; set; } | |
public bool EnableMetrics { get; set; } | |
public bool ExposeExceptions { get; set; } | |
public bool SetFieldMiddleware { get; set; } | |
} |
To register your own middleware you have to jump through some extra hoops:
- Create a custom GraphQLExecutor and override the GetOptions method:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ValidationGraphQLExecutor<TSchema> : DefaultGraphQLExecuter<TSchema> | |
where TSchema : ISchema | |
{ | |
private readonly GraphQLOptions options; | |
public ValidationGraphQLExecutor( | |
TSchema schema, | |
IDocumentExecuter documentExecuter, | |
IOptions<GraphQLOptions> options, | |
IEnumerable<IDocumentExecutionListener> listeners, | |
IEnumerable<IValidationRule> validationRules) | |
: base(schema, documentExecuter, options, listeners, validationRules) => | |
this.options = options.Value; | |
protected override ExecutionOptions GetOptions( | |
string operationName, | |
string query, | |
Inputs variables, | |
object context, | |
CancellationToken cancellationToken) | |
{ | |
var options = base.GetOptions(operationName, query, variables, context, cancellationToken); | |
if (this.options.SetFieldMiddleware) | |
{ | |
options.FieldMiddleware.Use<ValidationMiddleware>(); | |
} | |
return options; | |
} | |
} |
- Register this Executor instance in your IoC container(here I'm using StructureMap):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ServerRegistry : Registry | |
{ | |
public ServerRegistry() | |
{ | |
For(typeof(IGraphQLExecuter<>)).Use(typeof(ValidationGraphQLExecutor<>)); | |
} | |
} |