4
votes

Still digging into CQRS implementations experiment, and I decided to start over my Blog from scratch and to use it as a Sandbox.

I read a lot about bounded context, it seems to me that this is the most delicate approach in all this, and maybe the most difficult thing to explain and to apply in a real project.

Fortunately, my domain here is very simple ;-)

I try to identify the different bounded contexts and to determine which model becomes the aggregate root in each of these contexts.

The domain rules are really simple:

  • When a writer composes a blog post he MUST choose a category to save his post in, and he optionally can select multiple tags for improving his post visibility

  • When a reader visits the Blog, he can browse blog posts by category or by tags

With only these rules, we already get several bounded contexts, am I right ?

  • User (writer) composes a post context. In these context, the Post is the aggregate root

  • User (reader) browses posts by category. In these context, the Category is the aggregate root.

  • User (reader) browses posts by tags. In this context, well, I'm not sure... ;-)

Am I thinking things right ?

Given I am (right), I wonder, in the implementation of this, who is responsible of creating the different objects and relationships ?

Take the context where an user composes a new blog post for instance, I really don't have any clue about where I should create tags instances and whether or not I should create a relationship between the Post and its tags in the write model. The same goes with the Category, no idea :p

Also, does a bounded context means a specific model ? Meaning that for each bounded context I would have a different object graph (in write model) ?

Need some brain wave to see this clear in my mind ;-)

For adding a new post, so far, my controller asks the command bus to handle a "ComposeCommand", the handler (PostService) creates a new "Post" instance, invokes a compose method on it and finally asks the write persistence to save the new Post.

The Post::compose() method raises a "PostComposedEvent" event which the read model listens to update its data.

In all this I don't know how to introduce "Category" and "Tags".

Thanks.

1
"my domain here is very simple". In that case you will probably have only 1 bounded context. Perhaps you are mistaking aggregates for bounded contexts?Steven

1 Answers

5
votes

With only these rules, we already get several bounded contexts, am I right ?

No, a blogging app will usually span only a single bounded context. It is when the models have distinct meanings within different contexts that you need multiple BCs. This typically occurs when the domain you're addressing gets somewhat large consisting of multiple sub-domains.

You will have multiple aggregates however - you can have multiple aggregate roots in a single BC. Determining the aggregates in your domain model is based on several factors. Primarily, an aggregate forms a consistency boundary around a cohesive set of behaviors associated with some root entity. For example, a Post is likely an AR as is a Writer (Author). For an in-depth look at aggregate design take a look at Effective Aggregate Design.

In all this I don't know how to introduce "Category" and "Tags".

Usually, a post category and a set of tags are specified as part of the command which creates the post - ComposeCommand in your case. Depending on whether you model a Category and Tag as aggregates or value objects, the command will either specify a CategoryId and TagIds, or simply values.