No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

CQRS

17/24
Recursos

¿Qué es CQRS y cómo puede mejorar tu arquitectura de software?

En el mundo del desarrollo de software, siempre buscamos herramientas y técnicas que nos ayuden a manejar de manera más eficiente nuestros sistemas y aplicaciones. Aquí es donde entra CQRS (Command Query Responsibility Segregation), una técnica que puede cambiar por completo la manera en que manejamos nuestras operaciones de lectura y escritura dentro de una aplicación.

¿Cómo funciona CQRS?

CQRS, o Segregación de Responsabilidades de Comandos y Consultas, se basa en la idea de separar las operaciones que alteran el estado del sistema de aquellas que simplemente consultan datos. Esto se traduce en dos componentes principales:

  1. Comandos: Operaciones de escritura que cambian el estado de algún objeto o sistema. Por ejemplo, guardar un usuario o modificar un atributo de una base de datos.

  2. Consultas: Operaciones de lectura que se encargan de recuperar información, como "dame todos los usuarios registrados en los últimos 30 días" o "obtén la fecha de la última venta".

Al separar estos componentes, logramos una estructura más eficiente y sencilla de mantener, especialmente en aplicaciones que necesitan escalar.

¿Por qué elegir CQRS?

Hay diversas razones para adoptar CQRS:

  • Escalabilidad: Algunas aplicaciones pueden requerir una administración más intensiva de las operaciones de lectura o escritura. Separando estas operaciones, cada componente puede escalar independientemente según las necesidades del sistema.

  • Mantenimiento: La separación de responsabilidades generalmente lleva a un código más limpio y comprensible, facilitando el mantenimiento de la aplicación a largo plazo.

  • Desempeño: Permite optimizar componentes específicos de acuerdo a su función principal (leer o escribir), mejorando el rendimiento general.

Ejemplo de implementación en C#

CQRS se podría implementar en C# utilizando una estructura de proyecto predefinida que enfatice las arquitecturas limpias. Por ejemplo:

public class CreateTodoListCommand : IRequest
{
    public string Title { get; set; }
}

// Handler para el comando CreateTodoList
public class CreateTodoListCommandHandler : IRequestHandler<CreateTodoListCommand, Result>
{
    private readonly TodoDbContext _context;

    public CreateTodoListCommandHandler(TodoDbContext context) 
    {
        _context = context;
    }

    public async Task<Result> Handle(CreateTodoListCommand request, CancellationToken cancellationToken)
    {
        var todoList = new TodoList { Title = request.Title };
        _context.TodoLists.Add(todoList);
        await _context.SaveChangesAsync(cancellationToken);

        return Result.Success(todoList.Id);
    }
}

En este ejemplo, el comando CreateTodoListCommand está diseñado específicamente para manejar la operación de creación de una lista de tareas, utilizando Entity Framework para interactuar con la base de datos.

¿Qué sucede con las consultas?

Las consultas se manejan de manera similar, pero se enfocan únicamente en recuperar datos:

public class GetTodosQuery : IRequest<IList<TodoList>>
{
}

public class GetTodosQueryHandler : IRequestHandler<GetTodosQuery, IList<TodoList>>
{
    private readonly TodoDbContext _context;

    public GetTodosQueryHandler(TodoDbContext context) 
    {
        _context = context;
    }

    public async Task<IList<TodoList>> Handle(GetTodosQuery request, CancellationToken cancellationToken)
    {
        return await _context.TodoLists.ToListAsync(cancellationToken);
    }
}

Este patrón asegura que el código esté limpio y que cada clase tenga una sola responsabilidad, mejorando la mantenibilidad y legibilidad del código.

¿Cómo consumir los comandos y consultas?

En una arquitectura que adopta CQRS, los controladores (en una API, por ejemplo) no interactúan directamente con las consultas o comandos. En lugar de eso, utilizan un mediador que maneja los eventos y consultas:

[HttpGet]
public async Task<ActionResult<IList<TodoList>>> GetTodos()
{
    var query = new GetTodosQuery();
    var result = await _mediator.Send(query);
    return Ok(result);
}

El uso de un framework como Mediator permite lanzar eventos para manejar consultas y comandos, promoviendo un desacoplamiento significativo entre las capas de la aplicación.

¿Dónde más se puede aplicar CQRS?

Además de operaciones dentro del código, CQRS se puede expandir a:

  • Métodos: Evitando mezclar operaciones de lectura/escritura en un único método.
  • Clases: Separando las clases en función de si gestionan comandos o consultas.
  • Servicios y backends: Implementando microservicios o backend dedicados para operaciones de lectura y otro para operaciones de escritura.

En escenarios más avanzados, incluso se puede aplicar CQRS a nivel de bases de datos, separando bases de datos dedicadas a operaciones de lectura y escritura, lo cual sería beneficioso en entornos de alta concurrencia.

Implementar CQRS es un paso importante hacia una arquitectura de software más robusta y escalable. Con un poco de práctica, verás cómo esta técnica puede transformar tu forma de desarrollar aplicaciones. ¡Anímate a investigar más sobre este tema y sigue aprendiendo!

Aportes 8

Preguntas 2

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Creo que la mejor manera de explicar este curso es con un proyecto de ejemplo e irlo desarrollando paso a paso.

Considero que lo mas importante es no confundir a CQRS con la separacion de base de datos de escritura y lectura eso es mas bien lo que puede hacer el repository o un sistema de replica de base datos. Si no mas bien que separa la escritura de la lectura y esto es muy importante ya que en la escritura usualmente consumimos casos de uso y el dominio por lo cual hay validaciones en la lectura es util que no existan validaciones porque algunas veces por ejemplo se cambia a una arquitectura limpia pero se debe mantener el código legacy por tanto puede que exista data “sucia”

CQRS

Command Query Reponsability Segregation

Se divide en comandos y consultas.

Comandos

  • Escritura.
  • Cambian el estado.

Consultas

  • Lectura.
  • Retornan resultados.

Esta idea se puede aplicar a varios niveles:

  • Métodos.
  • Clases.
  • Servicios.
  • Bases de datos.
Para cuando el curso que no sea un "abre bocas introductorio"?
  • **Carpeta “src”: **Esta carpeta contiene el código fuente principal del proyecto.

**Carpeta “Application”: **Contiene la lógica de aplicación y los casos de uso del sistema.
Carpeta “Domain”: Contiene las entidades, objetos de valor y reglas de dominio del sistema.
Carpeta “Infrastructure”: Contiene la implementación de infraestructura y servicios externos.
Carpeta “Persistence”: Contiene la lógica de persistencia y acceso a datos.
**Archivo “Colour.cs”: **Este archivo, ubicado en la carpeta “Domain/ValueObjects”, representa la clase Colour que define un objeto de valor para representar colores en el dominio del sistema. El archivo define métodos y propiedades relacionados con los colores, como la creación de instancias de colores, conversiones implícitas y explícitas a cadenas, y la lista de colores compatibles. También se definen constantes para colores comunes como blanco, rojo, naranja, amarillo, verde, azul, morado y gris.

En resumen, CQRS mejora la escalabilidad, el rendimiento y la mantenibilidad de una aplicación. Esto se debe a que los sistemas tienen diferentes requisitos para manejar comandos y consultas, y al segregarlos, se puede optimizar cada operación de manera independiente. * **Comandos (Commands)**: Son de tipo escritura, ya que accionan modificando datos, como crear, actualizar o eliminar información. * **Consultas (Queries)**: Son de tipo lectura, ya que están optimizadas para proporcionar respuestas rápidas a las solicitudes de datos.