In this article, we will learn how to build a Backend for Frontend (BFF) using Hot Chocolate, a .NET GraphQL framework. We will focus on integrating data from multiple microservices, understanding filtering, sorting, and pagination. Note that this article assumes you have a basic understanding of Hot Chocolate, which is not covered here.
What is Hot Chocolate?
Hot Chocolate is an open-source .NET GraphQL framework for creating scalable and high-performance APIs. It provides a developer-friendly experience and enables creating powerful and flexible GraphQL services.
Building a BFF using Hot Chocolate
Backend for Frontend (BFF) is a pattern where a dedicated backend service is created for each frontend application. This pattern simplifies communication between the frontend and various microservices. With Hot Chocolate, building a BFF becomes even more accessible due to its powerful GraphQL capabilities.
Integrating Data from Multiple Microservices
In a typical microservices-based architecture, integrating data from multiple microservices can be challenging. Hot Chocolate provides a convenient way to handle this problem.
1. Create Microservices
First, build your microservices using your preferred .NET technologies, such as ASP.NET Core Web APIs. Assume you have the following microservices:
-
EmployeeService -
DepartmentService
2. Create the BFF
Create a new ASP.NET Core Web API project for your BFF. Install the Hot Chocolate package using the following command:
dotnet add package HotChocolate.AspNetCore
3. Integrating Data with Hot Chocolate
In the BFF, create a GraphQL schema and leverage the Query and Field attributes to define the schema and data queries. Use Hot Chocolate's Resolver attribute to link the schema queries to the actual microservice methods.
[ExtendObjectType(Name = "Query")]
public class MyQuery
{
[ResolveFieldPolicy]
public IQueryable GetEmployees([Service] IEmployeeService employeeService)
{
return employeeService.GetEmployees();
}
[ResolveFieldPolicy]
public IQueryable GetDepartments([Service] IDepartmentService departmentService)
{
return departmentService.GetDepartments();
}
}
Filtering, Sorting, and Pagination
Hot Chocolate supports filtering, sorting, and pagination through the use of directives, extension methods, and interfaces.
1. Filtering
Define a FieldMiddleware for filtering. You can apply this middleware using the [UseFiltering] directive on any query.
public class FilteringMiddleware :
IFieldMiddleware
{
public async Task
```ExecuteAsync(IMiddlewareContext context, FieldDelegate next)
{
var inputValue = context.ArgumentValue<InputFilter>();
if (inputValue == null)
{
return await next(context);
}
var filterExpression = BuildFilterExpression(inputValue);
context.SetArgument("filterExpression", filterExpression);
return await next(context);
}
private Expression BuildFilterExpression(InputFilter inputFilter)
{
// Create expression here, e.g., using ExpressionBuilder
}
```
}
2. Sorting
Define an IOperationInterceptor for sorting on the query level using the [UseSorting] directive.
public class SortingInterceptor : IOperationInterceptor
{
public async Task
```InterceptAsync(IOperation operation,
CancellationToken cancellationToken = new())
{
var sortInput = operation.Input.GetArgument<InputSort>("sortInput");
if (sortInput != null)
{
// Apply Sorting logic
operation = ApplySorting(sortInput, operation);
}
return await operation.ExecuteAsync(cancellationToken);
}
}
3. Pagination
Implement pagination by defining a FieldMiddleware for the IQueryable query type using the [UsePagination] directive.
public class PaginationMiddleware :
IFieldMiddleware
{
public async Task ExecuteAsync(IMiddlewareContext context, FieldDelegate next)
{
var paginationInput = context.ArgumentValue<InputPagination>();
if (paginationInput == null)
{
return await next(context);
}
var query = (IQueryable)context.ArgumentValue;
// Apply pagination here
query = ApplyPagination(paginationInput, query);
context.SetArgument("paginatedQuery", query);
return await next(context);
}
}
- Hot Chocolate simplifies managing interactions between multiple microservices.
- Filtering, sorting, and pagination can be implemented using middleware and directives.
References
- Hot Chocolate - The GraphQL framework for .NET
- Microservices.io (Microservices reference and best practices)