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
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.
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
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; }
}
}
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);
}
}
}
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);
}
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.
Top comments (0)