The Read Model

The Read Model, also known as the Query Model, is a pure denormalized data model lifted from Domain concerns. In fact, with CQRS, all the read concerns are treated as reporting processes, an infrastructure concern. In general, when using CQRS, the Read Model is subject to the needs of the UI and how complex the views compounding the UI are. In a situation where the Read Model is defined in terms of relational databases, the simplest approach would be to set one-to-one relationships between database tables and UI views. These database tables and UI views will be updated using Write Model projections triggered from the Domain Events published by the write side:

-- Definition of a UI view of a single post with its comments
CREATE TABLE single_post_with_comments (
id INTEGER NOT NULL,
post_id INTEGER NOT NULL,
post_title VARCHAR(100) NOT NULL,
post_content TEXT NOT NULL,
post_created_at DATETIME NOT NULL,
comment_content TEXT NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- Set up some data
INSERT INTO single_post_with_comments VALUES
(1, 1, "Layered" , "Some content", NOW(), "A comment"),
(2, 1, "Layered" , "Some content", NOW(), "The comment"),
(3, 2, "Hexagonal" , "Some content", NOW(), "No comment"),
(4, 2, "Hexagonal", "Some content", NOW(), "All comments"),
(5, 3, "CQRS", "Some content", NOW(), "This comment"),
(6, 3, "CQRS", "Some content", NOW(), "That comment");

-- Query it
SELECT * FROM single_post_with_comments WHERE post_id = 1;

An important feature of this architectural style is that the Read Model should be completely disposable, since the true state of the application is handled by the Write Model. This means the Read Model can be removed and recreated when needed, using Write Model projections.

Here we can see some examples of possible views within a blog application:

SELECT * FROM
posts_grouped_by_month_and_year
ORDER BY month DESC,year ASC;

SELECT * FROM
posts_by_tags
WHERE tag = "ddd";

SELECT * FROM
posts_by_author
WHERE author_id = 1;

It's important to point out that CQRS doesn't constrain the definition and implementation of the Read Model to a relational database. It depends exclusively on the needs of the application being built. It could be a relational database, a document-oriented database, a key-value store, or whatever best suits the needs of your application. Following the blog post application, we'll use Elasticsearch — a document-oriented database — to implement a Read Model:

class PostsController
{
public function listAction()
{
$client = new ElasticsearchClientBuilder::create()->build();

$response = $client-> search([
'index' => 'blog-engine',
'type' => 'posts',
'body' => [
'sort' => [
'created_at' => ['order' => 'desc']
]
]
]);

return [
'posts' => $response
];
}
}

The Read Model code has been drastically simplified to a single query against an Elasticsearch index. 

This reveals that the Read Model doesn't really need an object-relational mapper, as this might be overkill. However, the Write Model might benefit from the use of an object-relational mapper, as this would allow you to organize and structure the Read Model according to the needs of the application.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.4.181