Skip to content
This repository has been archived by the owner on Sep 12, 2023. It is now read-only.
/ HttpMediatR Public archive

A library that combines two awesome things: ASP.NET Core & MediatR, and makes your life easier when you're using them together. 💕

License

Notifications You must be signed in to change notification settings

RPM1984/HttpMediatR

Repository files navigation

HttpMediatR

A library that combines two awesome things: ASP.NET Core & MediatR, and makes your life easier when you're using them together. 💕

Status

Visual Studio Team services Codecov NuGet NuGet

Installation

Imgur

How to use

  • Instead of your input model implementing IRequest, implement IHttpRequest
  • Instead of your handler implementing IRequestHandler, inherit from HttpHandler
  • Implement the HandleAsync abstract method in your handler
  • Make use of the inherited helpers to return the appropriate responses
  • Marvel at your awesome code! ⭐

See the sample project for a demo on the above.

What problems does this library solve?

If you're using MediatR with ASP.NET Core, you'd probably be writing a lot of code like this:

public async Task<IActionResult> Index(Query query, CancellationToken cancellationToken)
{
    var result = await _mediator.Send(query, cancellationToken);
    if (result == null)
    {
        return NotFound();
    }
    return Ok(result);
}

Which is fine! But...with this library we can go one better, and make it look like this:

public Task<IActionResult> Index(Query query, CancellationToken cancellationToken)
            => _mediator.Send(query, cancellationToken);

So that's even better! 😎. We no longer need to write the boring "get something, see if it exists, return not found or ok depending on that blah blah", and it's just a 1 liner. In fact, you'll see in the source code there is a file called Router.cs instead of many controllers. This is because we don't really have controllers anymore..just a router passing on all the resposibility to handle the HTTP request to your MediatR handler, so there's no real need to seperate into multiple controllers (of course, feel free to do so if you like!)

Exceptions are pretty expensive..so ideally we'd like to avoid throwing them.

Here's an example of where you'd need to throw one in your MediatR handler:

public class Handler : IRequestHandler<Query, MyModel>
{
    private readonly SomeDbContext _db;

    public Handler(SomeDbContext db) => _db = db;

    protected async Task<MyModel> Handle(Query query,
										 CancellationToken cancellationToken)
    {
        var result = await _db.Get(query.Id, cancellationToken);
        if (result == null)
        {
            throw new Exception("Record not found.");
        }
        return result;

So there's a few problems there:

  • We're throwing an exception for a 404/not found (is it really an 'exception'?)
  • We have to handle that exception elsewhere (e.g in your ASP.NET Core error handler/some global filter)
  • We still have to handle returning the success of the response somewhere else (e.g your controller)

Now, we can do this:

public class Handler : HttpHandler<Query, MyModel>
{
    private readonly SomeDbContext _db;

    public Handler(SomeDbContext db) => _db = db;

    protected override async Task<HttpResponse<MyModel>> HandleAsync(Query query,
																	 CancellationToken cancellationToken)
    {
        var result = await _db.Get(query.Id, cancellationToken);
        if (result == null)
        {
            return NotFound();
        }
        return Ok(result));

So, we're not throwing exceptions anymore uncessarily, and everything to handle that HTTP request is there in the handler.

About

A library that combines two awesome things: ASP.NET Core & MediatR, and makes your life easier when you're using them together. 💕

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Languages