DDD/CQRS: Combining read models for UI requirements

cqrs pattern example
cqrs ddd
cqrs c#
cqrs pattern microservices
when to use cqrs
cqrs pattern java
cqrs microservices c#
cqrs vs crud

Let's use the classic example of blog context. In our domain we have the following scenarios: Users can write Posts. Posts must be cataloged at least in one Category. Posts can be described using Tags. Users can comment on Posts.

The four entities (Post, Category, Tag, Comment) are implemented as different aggregates because of I have not detected any rule for that an entity data should interfere in another. So, for each aggregate I will have one repository that represent it. Too, each aggregate reference others by his id.

Following CQRS, from this scenario I have deducted typical use cases that result on commands such as WriteNewPostCommand, PublishPostCommand, DeletePostCommand etc... along with their respective queries to get data from repositories. FindPostByIdQuery, FindTagByTagNameQuery, FindPostsByAuthorIdQuery etc...

Depending on which site of the app we are (backend or fronted) we will have queries more or less complex. So, if we are on the front page maybe we need build some widgets to get last comments, latest post of a category, etc... Queries that involve a simple Query object (few search criterias) and a QueryHandler very simple (a single repository as dependency on the handler class)

But in other places this queries can be more complex. In an admin panel we require to show in a table a relation that satisfy a complex search criteria. Might be interesting search posts by: author name (no id), categories names, tags name, publish date... Criterias that belongs to different aggregates and different repositories.

In addition, in our table of post we dont want to show the post along with author ID, or categories ID. We need to show all information (name user, avatar, category name, category icon etc).

My questions are:

  • At infrastructure layer, when we design repositories, the search methods (findAll, findById, findByCriterias...), should have return the corresponding entity referencing to all associations id's? I mean, If a have a method findPostById(uuid) or findPostByCustomFilter(filter), should return a post instance with a reference to all categories id it has, all tags id, and author id that it has? Or should my repo have some kind of method that populates a given post instance with the associations I want?

  • If I want to search posts created from 12/12/2014, written by John, and categorised on "News" and "Videos" categories and tags "sci-fi" and "adventure", and get the full details of each aggregate, how should create my Query and QueryHandler?

a) Create a Query with all my parameters (authorName, categoriesNames, TagsNames, if a want retrive User, Category, Tag association full detailed) and then his QueryHandler ensamble the different read models in a only one. Or...

b) Create different Queries (FindCategoryByName, FindTagByName, FindUserByName) and then my web controller calls them for later call to FindPostQuery but now passing him the authorid, categoryid, tagid returned from the other queries?

The b) solution appear more clean but it seems me more expensive.

How to deal with UI data requirements in DDD, Your Query/View models are being created for data purpose; They are not part of your domain. You typically use Domain modeling for writes,� I think I'm actually embracing CQRS whilst remaining pragmatic when I say that if a business requirements is data-driven to satisfy a UI, I'd have the UI or query layers worry about this but leave domain and write side out of it as long as I can guarantee that the info will be at UI and the read side is independently scalable, consistent

From CQRS you will have a separeted Stack for Queries and Commands. Your query stack should represent a diferente module, namespace, dll or package at your project.

a) You will create one QueryModel and this query model will return whatever you need. If you are familiar with Entity Framework or NHibernate, you will create a Façade to hold this queries togheter, DbContext or Session.

b) You can create this separeted queries, but saying again, if you are familiar with any ORM your should return the set that represents the model, return every set as IQueryable and use LET (Linq Expression Trees) to make your Query stack more dynamic.

Using Entity Framework and C# for exemple:

public class QueryModelDatabase : DbContext, IQueryModelDatabase
{
    public QueryModelDatabase() : base("dbname")
    {
        _products = base.Set<Product>();
        _orders = base.Set<Order>();
    }

    private readonly DbSet<Order> _orders = null;
    private readonly DbSet<Product> _products = null;

    public IQueryable<Order> Orders
    {
        get { return this._orders.Include("Items").Include("Items.Product"); }
    }

    public IQueryable<Product> Products
    {
        get { return _products; }
    }
}

Then you should do queries the way you need and return anything:

using (var db = new QueryModelDatabase())
{
    var queryable = from o in db.Orders.Include(p => p.Items).Include("Details.Product")
                    where o.OrderId == orderId
                    select new OrderFoundViewModel
                    {
                        Id = o.OrderId,
                        State = o.State.ToString(),
                        Total = o.Total,
                        OrderDate = o.Date,
                        Details = o.Items
                    };
    try
    {
        var o = queryable.First();
        return o;
    }
    catch (InvalidOperationException)
    {
        return new OrderFoundViewModel();
    }
}

CQRS pattern, Command and Query Responsibility Segregation (CQRS) pattern and prevents update commands from causing merge conflicts at the domain level. access layer, and the complexity of queries required to retrieve information. CQRS separates reads and writes into different models, using commands� DDD/CQRS: Combining read models for UI requirements 7 DDD/CQRS/ES Implement aggregate member using graph database aka using an immediately consistent readModel as entity collection

With simple applications like this, it's easier to not get distracted by aggregates. Do event sourcing, subscribe to the events by one set of tables that is easy to query the way you want.

Another words, it sounds like you're main goal is to be able to query easily for the scenarios you describe. Start with that end goal. Now write your event handler to adjust your tables accordingly.

Start with events and the UI. Then everything else will fit easily. Google "Event Modeling" as it will help you formulate ideas sound what and how you want to build these style of applications.

DDD / CQRS aggregate modelling, read models and bounded , I've spent some time adapting ddd + cqrs with eventsourcing, read the Blue book I improved that situation a little by merging multiple commands into one on its events and UI read model that collects all events necessary for ui. Validating ability to send command before sending will require every client� If the write model generates events for all updates, you can structure read models as Event Posters, allowing them to be Memory Images and thus avoiding a lot of database interactions. CQRS is suited to complex domains, the kind that also benefits from Domain-Driven Design.

I can see three problems in your approach and they need to be solved separately:

  1. In CQRS the Queries are completely separate from the Commands. So, don't try to solve your queries with your Commands pipelines repositories. The point of CQRS is precisely to allow you to solve the commands and queries in very different ways, as they have very different requirements.

  2. You mention DDD in the question title, but you don't mention your Bounded Contexts in the question itself. If you follow DDD, you'll most likely have more than one BC. For example, in your question, it could be that CategoryName and AuthorName belong to two different BCs, which are also different from the BC where the blog posts are. If that is the case and each BC properly owns its own data, the data that you want to search by and show in the UI will be stored potentially in different databases, therefore implementing a query in the DB with a join might not even be possible.

  3. Searching and Reading data are two different concerns and can/should be solved differently. When you search, you get some search criteria (including sorting and paging) and the result is basically a list of IDs (authorIds, postIds, commentIds). When you Read data, you get one or more Ids and the result is one or more DTOs with all the required data properties. It is normal that you need to read data from multiple BCs to populate a single page, that's called UI composition.

So if we agree on these 3 points and especially focussing on point 3, I would suggest the following:

Figure out all the searches that you want to do and see if you can decompose them to simple searches by BC. For example, search blog posts by author name is a problem, because the author information could be in a different BC than the blog posts. So, why not implement a SearchAuthorByName in the Authors BC and then a SearchPostsByAuthorId in the Posts BC. You can do this from the Client itself or from the API. Doing it in the client gives the client a lot of flexibility because there are many ways a client can get an authorId (from a MyFavourites list, from a paginated list or from a search by name) and then get the posts by authorId is a separate operation. You can do the same by tags, categories and other things. The Post will have Ids, but not the extra details about those IDs.

Potentially, you might want more complicated searches. As long as the search criteria (including sorting fields) contain fields from a single BC, you can easily create a read model and execute the search there. Note that this is only for the search criteria. If the search result needs data from multiple BCs you can solve it with UI composition. But if the search criteria contain fields from multiple BCs, then you'll need some sort of Search engine capable of indexing data coming from multiple sources. This is especially evident if you want to do full-text search, search by categories, tags, etc. with large quantities of data. You will need to use some specialized service like Elastic Search and it won't belong to any of your existing BCs, it'll be like a supporting service.

CQRS: What? Why? How?. CQRS is a useful pattern to reason , Reads, Writes, DDD, Event Sourcing, Eventual Consistency, why should… CQRS (combined with DDD) forces us to put strong constraints and have The Read Models can be read by front-ends or by APIs, it does not matter. data lifecycles, data ownerships, business requirements, and a lot about the� By the way, queries are not on these diagrams because they don’t belong to the onion architecture. Domain modeling is for writes, not reads. Reading data is simple, you don’t need DDD to do that. But you do need a rich and highly encapsulated domain model for data modification.

Event Sourcing and CQRS, Because the operational requirements for executing commands and flow in CQRS goes hand in hand with the Task-Based User Interface pattern. Back in 2016 in his talk A Decade of DDD, CQRS, Event Sourcing Just as the entity state, the read model state is the left fold of all the event it processes. Browse other questions tagged asp.net-mvc domain-driven-design cqrs or ask your own question. DDD/CQRS: Combining read models for UI requirements. 1.

Domain-driven design, Domain-driven design (DDD) is the concept that the structure and language of software code DDD connects the implementation to an evolving model. Yet when code based on distinct models is combined, software becomes buggy, While CQRS does not require DDD, domain-driven design makes the distinction � In the second part of this workshop I will show you a functional approach that allows you to actually reuse your domain types, your read-models and even your domain logic from the backend on the frontend. This is possible by combining CQRS/Event-Sourcing with an expressive frontend using the MVU pattern by applying an overall messaging

CQRS, CQRS stands for Command Query Responsibility Segregation. use a different model to update information than the model you use to read information. one, or forming virtual records by combining information for different places. that we interact with via CRUD, we can easily move to a task-based UI. CQRS is a useful pattern to reason about the activities of a specific domain. But it definitely comes with a steep learning curve. Reads, Writes, DDD, Event Sourcing, Eventual Consistency, why