Generate your own application with the CQRS design pattern thanks to JHipster.NET

zenrac

Zenrac

Posted on July 23, 2021

Generate your own application with the CQRS design pattern thanks to JHipster.NET

JHipster CQRS

Overview

JHipster is a famous generator allowing you to generate modern applications.

One of its official blueprints is called JHipster.NET. It allows to override the back-end part in asp.net core (instead of Java spring boot).

To take advantage of this blueprint, we will generate a modern application which implements the Mediator and CQRS pattern.

Why CQRS ?

CQRS stands for Command Query Responsibility Segregation. In .NET you have the possibility to easily implement this pattern thanks to MediatR.

This pattern separates a service’s write tasks from its read tasks. While reading and writing to the same database is acceptable for small applications, distributed applications operating at web-scale require a segmented approach.

Pros

  • Modern pattern that is more and more used in many projects.
  • It’s secure, it allows to make sure that queries are not able to do “write” operations, as they souldn’t do.
  • Separating write and read activities allows you to use the best database technology for the task at hand, for example, a SQL database for writing and a non-SQL database for reading.
  • It also helps with balance loading and performance balancing. Read activity tends to be more frequent than writing, you can reduce response latency by placing read data sources in strategic geolocations for better performance.

Cons

  • You have to ensure that your data is consistant between your database.
  • This pattern is difficult/nearly impossible to implement to an already existing project.

Hopefully, thanks to JHipster implementing CQRS to your application isn’t a big deal.

MediatR

Mediator pattern
In order to easily implement the CQRS pattern, JHipster uses MediatR which implements the Mediator pattern.

The Mediator pattern adds a layer called Application which allows to separate your commands and queries. Meaning that your controllers delegate all the CRUD logic to your Application layer, then your Application layer finds which database it needs to interact with, which service/repository to use etc...

Taking advantage of MediatR to implements CQRS

The easiest way to implement CQRS with the Mediator pattern is to add ReadOnlyRepositories. Those repositories will be used by queries, when your commands will use the original repositories. Thanks to that, your commands and queries will be separated.

CQRS with JHipster

Installation

You may find more information about how to generate your ASP.NET Core application with JHipster.NET in this post.

When generating your application, you can choose to use CQRS.
Choose to enable CQRS
Make sure to answer Y to enable CQRS.

Enabling it will generate a new “Application” layer (a new solution in your C#) for your commands and queries.

├── Namespace.Application
│   ├── Commands                             - Your commands
│   │   ├── MyEntity                         - Your entity
│   │   │   ├── MyEntityCreateCommand        - A command
│   │   │   ├── MyEntityCreateCommandHandler - A command handler
│   ├── Queries                              - Your queries
│   │   ├── MyEntity                         - Your entity
│   │   │   ├── MyEntityGetQuery             - A query
│   │   │   ├── MyEntityGetQueryHandler      - A query handler
├── Namespace.Crosscutting
├── Namespace.Domain
├── Namespace.Domain.Services
├── Namespace.Dto
├── Namespace.Infrastructure
Enter fullscreen mode Exit fullscreen mode

How to create queries/commands

In order to create your own commands and/or queries you have to create two classes :

  • A command/query
  • An handler for it

Automatically

JHipster allows to automatically generates entities. Read this article to get started. Of course it will automatically generates your entities following the CQRS pattern with their commands/queries.

Manually

If you want to create your very own commands/queries, here’s an example :
First, let’s create a query MyEntityGetQuery.cs:

namespace MyCompany.Application.Queries {
    public class MyEntityGetQuery : IRequest<MyEntity>
    {
        public long Id { get; set; }
    }
}
Enter fullscreen mode Exit fullscreen mode

This Query should have an Id and returns a MyEntity object. Here’s the handler MyEntityGetQueryHandler.cs :

namespace MyCompany.Application.Queries {
    public class MyEntityGetQueryHandler : IRequestHandler<MyEntityGetQuery, MyEntity>
    {
        private IReadOnlyMyEntityRepository _myEntityRepository;
        public MyEntityGetQueryHandler(IReadOnlyMyEntityRepository myEntityRepository)
        {
            _myEntityRepository = myEntityRepository;
        }
        public Task<MyEntity> Handle(MyEntityGetQuery request,
            CancellationToken cancellationToken)
        {
            return _myEntityRepository.QueryHelper()
                .GetOneAsync(myEntity => myEntity.Id == request.Id);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Please note that we are using a ReadOnlyRepository rather than a service in order to do the segregation between Commands and Queries. Lastly, create your routing method within your controller :

[HttpGet("my-entity/{id}")]
public async Task<IActionResult> GetMyEntity([FromRoute] long id)
{
    var result = await _mediator.Send(new MyEntityGetQuery { Id = id });
    return ActionResultUtil.WrapOrNotFound(result);
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

Now you should be able to generate a modern CQRS Application thanks to JHipster !
Feel free to contribute to JHipster.NET’s GitHub repository and don’t forget to put a star if you liked it.

💖 💪 🙅 🚩
zenrac
Zenrac

Posted on July 23, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related