An Interest In:
Web News this Week
- April 3, 2024
- April 2, 2024
- April 1, 2024
- March 31, 2024
- March 30, 2024
- March 29, 2024
- March 28, 2024
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 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:
- Keep everything in command/query handlers
- Keep API as thin as possible
- Execute handlers within Azure Functions (keeping them thin as well)
- 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:
- Response without content:
return Success()
- Response with some content:
return Success(responseObj)
- 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
Original Link: https://dev.to/kedzior_io/easiest-way-to-build-the-fastest-rest-api-in-c-and-net-7-using-cqrs-2bk8
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To