Back to book

GraphQL Serverside in C#Bot

An overview the GraphQL implementation on the C#Bot serverside

GraphQL Serverside in C#Bot

In this article we go over the flow of data when a request is sent to the GraphQL controller. For this article we are going to be using the Fishnatics example project.


When submitting an API request to /api/graphql the data will hit the controller found at serverside/src/Controllers/GraphQlController.cs. The data sent to this controller will follow the standards provided by GraphQL.

File By File Breakdown



This is the entry point into the application and the request will almost always be hitting the Post function.

public async Task<ExecutionResult> Post(CancellationToken cancellation)
    await _identityService.RetrieveUserAsync();

    var parsedRequest = await ParsePostBody(cancellation);

    var result = await _graphQlService.Execute(

    return RenderResult(result);

In this function you can see we retrieve the user who made the request, parse the post body and then execute the query in the GraphQL service.



This file mostly contains the construction of an options object and then calling the execute method of the GraphQL executor.

var result = await _executer.ExecuteAsync(executionOptions)

The GraphQL executor is a class provided by the library GraphQL.NET. This executor will read the GraphQL schema the bot has defined, and either execute one of the functions inside of it, or fail if the query was invalid.



This is where the GraphQL schema is defined on the serverside. A schema is a basic class which contains 2 other classes, a query and mutation. These query and mutation classes provide the functions used to execute a GraphQL request.

public class FishnaticsSchema : Schema
        public FishnaticsSchema(IDependencyResolver resolver) : base(resolver)
            Query = resolver.Resolve<FishnaticsQuery>();
            Mutation = resolver.Resolve<FishnaticsMutation>();
            // % protected region % [Add any extra schema constructor options here] off begin
            // % protected region % [Add any extra schema constructor options here] end

        // % protected region % [Add any schema methods here] off begin
        // % protected region % [Add any schema methods here] end

While this article will look at the query class, it is important to note the mutation class will follow the same principals. If we take a look at the constructor for the query class we can see this.

public FishnaticsQuery(IEfGraphQLService<FishnaticsDBContext> efGraphQlService) : base(efGraphQlService)
    // Add query types for each entity
    AddModelQueryField<FishEntityType, FishEntity>("FishEntity");
    AddModelQueryField<TankEntityType, TankEntity>("TankEntity");
    AddModelQueryField<SpeciesEntityType, SpeciesEntity>("SpeciesEntity");
    AddModelQueryField<AdminEntityType, AdminEntity>("AdminEntity");
    AddModelQueryField<FishnaticEntityType, FishnaticEntity>("FishnaticEntity");

    // Add query types for each many to many reference

    // % protected region % [Add any extra query config here] off begin
    // % protected region % [Add any extra query config here] end

This will call the AddModelQueryField for each different type of entity in the model to construct the functions defined for the entity in the GraphQL API. The argument provided for this function is the string that shall be used in the name for the GraphQL functions and the 2 generic parameters are the GraphQL type class and the Entity Framework model class. We will come back to the GraphQL type class later in the article.

If we take a look at the AddModelQueryField we can see it looks like the following.

public void AddModelQueryField<TModelType, TModel>(string name)
    where TModelType : ObjectGraphType<TModel>
    where TModel : class, IOwnerAbstractModel, new()
        typeof(TModelType)).Description = $"Query for fetching multiple {name}s";

        name: name,
        resolve: QueryHelpers.CreateResolveFunction<TModel>(),
        graphType: typeof(TModelType)).Description = $"Query for fetching a single {name}";

    // More functions below ...

To break down one of these calls, the first argument is the name of the query that can be called from the GraphQL API. The second argument is the query resolver (basically a callback function) that will be run when the query is executed. The final argument is the GraphQL model type that shall be used as the return type for the query.

When a query is executed, it will run the resolve function and then use the model type to return a value to the executor which is then returned by the API.

GraphQL Query Resolvers


The specific resolver we are going to look at for this article is CreateResolveFunction, which fetches query data.

public static Func<ResolveFieldContext<object>, IQueryable<TModel>> CreateResolveFunction<TModel>()
    where TModel : class, IOwnerAbstractModel, new()
    return context =>
        var graphQlContext = (JackenumGraphQlContext) context.UserContext;
        var crudService = graphQlContext.CrudService;
        var auditFields = AuditReadData.FromGraphqlContext(context);
        return crudService.Get<TModel>(auditFields: auditFields);

We can see this function constructs and returns a new function. This is so we can reuse the same resolver for all of our different entities. The first 3 lines are retrieving fields we need to execute the query. The final call is to the Get method of the CrudService which will create an Entity Framework query for this specific entity type and return it.

Model Types and Relations


A GraphQL type represents the values used as arguments and return types for the GraphQL functions. Taking a look at the model type for the species entity we can see there are 2 different classes inside of it. We will go over both of these.

public class SpeciesEntityType : EfObjectGraphType<FishnaticsDBContext, SpeciesEntity>
    public SpeciesEntityType(IEfGraphQLService<FishnaticsDBContext> service) : base(service)
        Description = @"A species of fish";

        // Add model fields to type
        Field(o => o.Id, type: typeof(IdGraphType));
        Field(o => o.Created, type: typeof(DateTimeGraphType));
        Field(o => o.Modified, type: typeof(DateTimeGraphType));
        Field(o => o.Name, type: typeof(StringGraphType)).Description(@"The species name");
        // % protected region % [Add any extra GraphQL fields here] off begin
        // % protected region % [Add any extra GraphQL fields here] end

        // Add entity references

        // GraphQL reference to entity FishEntity via reference FishSpecies
        IEnumerable<FishEntity> FishSpeciessResolveFunction(ResolveFieldContext<SpeciesEntity> context)
            var graphQlContext = (FishnaticsGraphQlContext) context.UserContext;
            var filter = SecurityService.CreateReadSecurityFilter<FishEntity>(graphQlContext.IdentityService, graphQlContext.UserManager, graphQlContext.DbContext);
            return context.Source.FishSpeciess.Where(filter.Compile());
        AddNavigationListField("FishSpeciess", (Func<ResolveFieldContext<SpeciesEntity>, IEnumerable<FishEntity>>) FishSpeciessResolveFunction);
        AddNavigationConnectionField("FishSpeciessConnection", FishSpeciessResolveFunction);

        // % protected region % [Add any extra GraphQL references here] off begin
        // % protected region % [Add any extra GraphQL references here] end

In this class, we can see the individual fields defined in the entity model for this entity. We can see the first four fields are defining the entity attributes. The second part of the code first defines an inline function for resolving the reference, which is then added as a callback for a navigation field. This will allow the related entities to queried in one request. A navigation field is translated into a .Include call in Entity Framework.

Notes and Further Information

Even though there is a large amount of bot written code, most of it is a configuration for the 2 different GraphQL libraries that we use.

  • GraphQL.Net - This library is used to provide the GraphQL executor that processes GraphQL queries as well as the schema that defines the entire API.
  • GraphQL.EntityFramework - This library builds upon the previous one to enable native Entity Framework queries based on the defined model types.

For a more in depth look to the GraphQL.NET library I would strongly recommend looking that the Lynda course API Development in .NET with GraphQL. This video tutorial goes step by step on creating an ASP.NET GraphQL application from scratch.