Easiest way to build the fastest REST API in C# and .NET 7 using CQRS

Sometime ago I stumbled upon this amazing library built by amazing people: https://fast-endpoints.com

It was also featured on this platform https://dev.to/djnitehawk/building-rest-apis-in-net-6-the-easy-way-3h0d (written by the author).

I gave it a…


This content originally appeared on DEV Community and was authored by Artur Kędzior

Sometime ago I stumbled upon this amazing library built by amazing people: https://fast-endpoints.com

It was also featured on this platform https://dev.to/djnitehawk/building-rest-apis-in-net-6-the-easy-way-3h0d (written by the author).

I gave it a go and I was impressed how easy and fast it was to set it all up. Since I'm not a big fan of REPR pattern almost all my projects are using CQRS pattern with a help of MediatR ](https://github.com/jbogard/MediatR) I immediately started going over something similar that Fast Endpoints offer which is a command bus.

I immediately started to put the project together with certain goals:

  1. Keep everything in command/query handlers
  2. Keep API as thin as possible
  3. Execute handlers within Azure Functions (keeping them thin as well)
  4. Make handlers easily unit testable

I put all this up on Github FastArchitecture 🔥

The API endpoint ended up being a single line:

public class GetOrdersEndpoint : ApiEndpoint<GetOrders.Query, GetOrders.Response>
{
    public override void Configure()
    {
        Get("orders/list");
        AllowAnonymous();
        ResponseCache(60);
    }

    public override async Task HandleAsync(GetOrders.Query request, CancellationToken ct)
        => await SendAsync(await request.ExecuteAsync(ct));
}

The Query handler in a self contained class that contains:

  • Query definition (the input)
  • Query response (the output)
  • Handler (stuff that happens within execution)
public static class GetOrders
{
    public sealed class Query : IQuery<IHandlerResponse<Response>>
    {
    }

    public sealed class Response
    {
        public IReadOnlyCollection<OrderListModel> Orders { get; private set; }

        public Response(IReadOnlyCollection<Domain.Order> orders)
        {
            Orders = orders.Select(OrderListModel.Create).ToList();
        }
    }

    public sealed class Handler : QueryHandler<Query, Response>
    {
        public Handler(IHandlerContext context) : base(context)
        {
        }

        public override async Task<IHandlerResponse<Response>> ExecuteAsync(Query query, CancellationToken ct)
        {
            var orders = await DbContext
                .Orders
                .ToListAsync(ct);

            return Success(new Response(orders));
        }
    }
}

Here is an example of Command handler with built-in Fluent Validation and fire and forget style:

public static class ConfirmAllOrders
{
    public sealed class Command : ICommand
    {
        public string Name { get; set; } = "";
    }

    public sealed class MyValidator : Validator<Command>
    {
        public MyValidator()
        {
            RuleFor(x => x.Name)
                .MinimumLength(5)
                .WithMessage("Order name is too short!");
        }
    }

    public sealed class Handler : Abstractions.CommandHandler<Command>
    {
        public Handler(IHandlerContext context) : base(context)
        {
        }

        public override async Task<IHandlerResponse> ExecuteAsync(Command command, CancellationToken ct)
        {
            var orders = await DbContext
                   .Orders
                   .ToListAsync(ct);

            orders.ForEach(x => x.SetConfrimed());

            await DbContext.SaveChangesAsync(ct);

            return Success();
        }
    }
}

Handlers allow 3 possible responses:

  1. Response without content:
return Success()
  1. Response with some content:
return Success(responseObj)
  1. An error*:
return Error("I felt a great disturbance in the Force, as if millions of voices suddenly cried out in terror and were suddenly silenced. I fear something terrible has happened.")

*soon to be implemented

Here is an example of running it from ** Azure Functions**:

public class ConfirmAllOrdersFunction : FunctionBase<ConfirmAllOrdersFunction>
{

    public ConfirmAllOrdersFunction(ILogger logger) : base(logger)
    {
    }

    [Function(nameof(ConfirmAllOrdersFunction))]
    public async Task Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req)
    {
        var command = new ConfirmAllOrders.Command();

        await ExecuteAsync<ConfirmAllOrders.Command>(command, req.FunctionContext);
    }
}

🔥 Interested?
🔥 Checkout the complete source code on Github FastArchitecture


This content originally appeared on DEV Community and was authored by Artur Kędzior


Print Share Comment Cite Upload Translate Updates
APA

Artur Kędzior | Sciencx (2023-04-25T21:25:40+00:00) Easiest way to build the fastest REST API in C# and .NET 7 using CQRS. Retrieved from https://www.scien.cx/2023/04/25/easiest-way-to-build-the-fastest-rest-api-in-c-and-net-7-using-cqrs/

MLA
" » Easiest way to build the fastest REST API in C# and .NET 7 using CQRS." Artur Kędzior | Sciencx - Tuesday April 25, 2023, https://www.scien.cx/2023/04/25/easiest-way-to-build-the-fastest-rest-api-in-c-and-net-7-using-cqrs/
HARVARD
Artur Kędzior | Sciencx Tuesday April 25, 2023 » Easiest way to build the fastest REST API in C# and .NET 7 using CQRS., viewed ,<https://www.scien.cx/2023/04/25/easiest-way-to-build-the-fastest-rest-api-in-c-and-net-7-using-cqrs/>
VANCOUVER
Artur Kędzior | Sciencx - » Easiest way to build the fastest REST API in C# and .NET 7 using CQRS. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2023/04/25/easiest-way-to-build-the-fastest-rest-api-in-c-and-net-7-using-cqrs/
CHICAGO
" » Easiest way to build the fastest REST API in C# and .NET 7 using CQRS." Artur Kędzior | Sciencx - Accessed . https://www.scien.cx/2023/04/25/easiest-way-to-build-the-fastest-rest-api-in-c-and-net-7-using-cqrs/
IEEE
" » Easiest way to build the fastest REST API in C# and .NET 7 using CQRS." Artur Kędzior | Sciencx [Online]. Available: https://www.scien.cx/2023/04/25/easiest-way-to-build-the-fastest-rest-api-in-c-and-net-7-using-cqrs/. [Accessed: ]
rf:citation
» Easiest way to build the fastest REST API in C# and .NET 7 using CQRS | Artur Kędzior | Sciencx | https://www.scien.cx/2023/04/25/easiest-way-to-build-the-fastest-rest-api-in-c-and-net-7-using-cqrs/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.