ASP.NET Core (Handler to Endpoint)
Shiny Mediator now can map up your request handlers to ASP.NET Core endpoints using the minimal API. This saves you the effort of implementing the following boilerplate over and over and over again
app.MapPost("/api/MyResultHandler", async (IMediator mediator, MyRequest request, CancellationToken ct) =>{ return await mediator.Request(request, ct);});The only thing that changes in this setup is the http method type, request type, and route. Now, all you have to do is following;
-
On your request handler (void or result based), add
[MediatorHttpPost("OperationId", "MyRoute")]or[MediatorHttpPut("OperationId", "MyRoute")](GET & DELETE attributes also available) attribute to the handler.[MediatorScoped] // if you want this registration through source gen (best practice) - you can only used scoped for handlers in ASPNET[MediatorHttpGroup("/routes", RequiresAuthorization = true)]public class MyHandler : IRequestHandler<MyRequest, MyResult>{[MediatorHttpPost("MyOperation", "/my")] // creates a route with the operationId of "MyOperation" and a route of "/routes/my"public async Task<MyResult> Handle(MyRequest request, IMediatorContext context, CancellationToken ct){return new MyResult();}} -
In your host startup, add the following after your build your app. Here is a full-ish sample
var builder = WebApplication.CreateBuilder(args);// Use mediator registry method if using [MediatorScoped] attributes to register your handlersbuilder.Services.AddShinyMediator(x => x.AddMediatorRegistry());// OR ADD YOUR HANDLER(S) manuallyservices.AddScopeAsImplementedInterfaces<MyHandler>();var app = builder.Build();// ADD REGISTERED HANDLERS THAT ARE ATTRIBUTED TO THE HTTP ENDPOINTSapp.MapGeneratedMediatorEndpoints());app.Run();
Here is a list of all the properties supported by the Http attributes
public class MediatorHttpAttribute(string operationId, string uriTemplate, HttpMethod httpMethod) : Attribute{ public string OperationId => operationId; public string UriTemplate => uriTemplate; public HttpMethod Method => httpMethod;
public bool RequiresAuthorization { get; set; } public string[]? AuthorizationPolicies { get; set; } public string? DisplayName { get; set; } public string? GroupName { get; set; } public string[]? Tags { get; set; } public string? Description { get; set; } public string? Summary { get; set; } public bool UseOpenApi { get; set; } = true; public string? CachePolicy { get; set; } public string? CorsPolicy { get; set; } public bool ExcludeFromDescription { get; set; } public string? RateLimitingPolicy { get; set; } public bool AllowAnonymous { get; set; }}MediatorHttpGet & MediatorHttpDelete parameters can only be set on the route or querystring. All http handlers are automatically generated to map against a scoped mediator handler
Minimal API Registration
Section titled “Minimal API Registration”Minimal API allows you some fine grained control that attribute registration may restrict as it returns the standard RouteHandleBuilder object that
ASP.NET registration returns
var builder = WebApplication.CreateBuilder(args);
// Use mediator registry method if using [MediatorScoped] attributes to register your handlersbuilder.Services.AddShinyMediator(x => x.AddMediatorRegistry());var app = builder.Build();
// fluent registration can be mixed with the attribute registrationapp.MapMediatorGet<MappedRequest, string>("/mapped").WithOpenApi();
app.Run();Server Sent Events
Section titled “Server Sent Events”Server Sent Events (SSE) allow you to stream data from the server to the client over HTTP. Shiny Mediator now supports sending stream requests as SSE endpoints.
This feature comes in two flavours
Stream Requests
Section titled “Stream Requests”We take your standard stream request handlers and allow you to send them as SSE endpoints. Here is an example of a stream request to SSE.
app.MapGet( "/sse", ( [FromServices] IMediator mediator, [FromServices] IHttpContextAccessor context, // remember to call services.AddHttpContextAccessor() in your startup [AsParameters] TickerStreamRequest request // a stream request ) => mediator.RequestServerSentEvents(request, context)).ExcludeFromDescription();Event Streams
Section titled “Event Streams”Maybe you want to listen for a specific event publication through mediator. This easy extension method allows you to do just that.
public class MyEvent : IEvent;
app.MapGet( "/subscribe", ( [FromServices] IMediator mediator, [FromServices] IHttpContextAccessor context // remember to call services.AddHttpContextAccessor() in your startup ) => mediator.EventStreamToServerSentEvents<MyEvent>(context)).ExcludeFromDescription();