Skip to content

Instantly share code, notes, and snippets.

@BenMakesGames
Created July 10, 2023 20:42
Show Gist options
  • Save BenMakesGames/1d25937e139c4fd344983019f9fa1ac3 to your computer and use it in GitHub Desktop.
Save BenMakesGames/1d25937e139c4fd344983019f9fa1ac3 to your computer and use it in GitHub Desktop.
MediatRPC

Example use:

builder.Services.AddMediatR(...);

...

app.MapGet<GetFruit.Request, GetFruit.Response>("/getFruit");
app.MapPost<CreateFruit.Request, CreateFruit.Response>("/createFruit");
app.MapPost<DeleteFruit.Request>("/deleteFruit");

Assuming there exist MediatR handlers:

public sealed class GetFruit: IRequestHandler<GetFruit.Request, GetFruit.Response?>
{
    public async Task<Response?> Handle(Request request, CancellationToken cancellationToken)
    {
        ...

        return new Response(...);
    }

    public sealed record Request(Guid Id) : IRequest<Response>;
    public sealed record Response(...);
}


public sealed class CreateFruit: IRequestHandler<CreateFruit.Request, CreateFruit.Response>
{
    public async Task<Response> Handle(Request request, CancellationToken cancellationToken)
    {
        ...

        return new Response(...);
    }

    public sealed record Request(...) : IRequest<Response>;
    public sealed record Response(Guid Id);
}

public sealed class DeleteFruit: IRequestHandler<DeleteFruit.Request>
{
    public async Task Handle(Request request, CancellationToken cancellationToken)
    {
        ...
    }

    public sealed record Request(Guid Id) : IRequest;
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MediatR" Version="12.1.1" />
</ItemGroup>
</Project>
using MediatR;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace MediatRPC;
public static class WebApplicationExtensions
{
public static void MapGet<TRequest, TResponse>(this WebApplication app, string route) where TRequest: IRequest<TResponse>
=> app.MapGet(route, ([FromServices] IMediator mediator, [AsParameters] TRequest request) => mediator.Send(request));
public static void MapGet<TRequest>(this WebApplication app, string route) where TRequest: IRequest
=> app.MapGet(route, ([FromServices] IMediator mediator, [AsParameters] TRequest request) => mediator.Send(request));
public static void MapPost<TRequest, TResponse>(this WebApplication app, string route) where TRequest: IRequest<TResponse>
=> app.MapPost(route, ([FromServices] IMediator mediator, [FromBody] TRequest request) => mediator.Send(request));
public static void MapPost<TRequest>(this WebApplication app, string route) where TRequest: IRequest
=> app.MapPost(route, ([FromServices] IMediator mediator, [FromBody] TRequest request) => mediator.Send(request));
// the following are not typically used in RPC-over-REST, but they're included in case you want them, anyway:
/*
public static void MapPut<TRequest, TResponse>(this WebApplication app, string route) where TRequest: IRequest<TResponse>
=> app.MapPut(route, ([FromServices] IMediator mediator, [FromBody] TRequest request) => mediator.Send(request));
public static void MapPut<TRequest>(this WebApplication app, string route) where TRequest: IRequest
=> app.MapPut(route, ([FromServices] IMediator mediator, [FromBody] TRequest request) => mediator.Send(request));
public static void MapPatch<TRequest>(this WebApplication app, string route) where TRequest: IRequest
=> app.MapPatch(route, ([FromServices] IMediator mediator, [FromBody] TRequest request) => mediator.Send(request));
public static void MapPatch<TRequest, TResponse>(this WebApplication app, string route) where TRequest: IRequest<TResponse>
=> app.MapPatch(route, ([FromServices] IMediator mediator, [FromBody] TRequest request) => mediator.Send(request));
public static void MapDelete<TRequest, TResponse>(this WebApplication app, string route) where TRequest: IRequest<TResponse>
=> app.MapDelete(route, ([FromServices] IMediator mediator, [FromBody] TRequest request) => mediator.Send(request));
public static void MapDelete<TRequest>(this WebApplication app, string route) where TRequest: IRequest
=> app.MapDelete(route, ([FromServices] IMediator mediator, [FromBody] TRequest request) => mediator.Send(request));
*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment