0

I have three bounded contexts: Users (generic subdomain), Groups (supporting subdomain) and Events (core domain). Basically users can create/join groups, create events within those groups, and sign up for events within group. This is for educational purposes, probably Users and Groups should be merged into one context. Anyway I need following read models:

  • group with list of all members and all active events (requires "data" from Users, Groups and Events)
  • event with list of all signed up group members (requires "data" from Events and Users)

The Users context is needed to get user profiles info for example.

So my idea is to have single separate project/microservice from those three bounded contexts that will have all read models needed by the UI. It will subscribe to domain events from all three contexts to build the read models. Is it a good idea?

On one side read model is kind of separate bounded context needed by the UI. On the other side it's a place which can cause some "conflicts" between teams working on other contexts, because they will want to update read model(s) according to their changes in bounded contexts.

The other approach (which I was using so far) is to have "smaller" read models in each bounded context / service, expose them through some API and use view-composition in API gateway level to build view models required by UI. However this is coupling all contexts/services and make the read model dependant on other services availability.

So it's very tempting to have one autonomous read model, independant from anything (only asynchronically on domain events).

1 Answer 1

2

As far as I understand the range of supported behavior, I would do it differently.

Microservices only really make sense if you either need operational scalability and/or organizational scalability. So assuming the latter based on your post, that only works if the services are really independent.

This means "requires data from" type of sentences already indicate that the services are not correctly separated. Also the term "bounded" in "bounded context" means that the context has a boundary. I.e. it does not need to refer to outside concepts. It is a functionally complete part of a larger system. It means it works in isolation, it can be independently developed and operated.

This includes the UI! If you have a single UI / you control the UI, don't separate it from the services. It will only cause dependencies between running systems and teams. Not a good thing to have.

In summary: Take a step back. If you want to have independent teams iterating fast and independently, any form of dependency is your enemy. If you design the system from scratch, you can design without hard dependencies.

9
  • I understand your point but to me it seems obvious that one team can work on users and groups for example (registration, login, inviting to groups, accepting invites and adding users to groups managing user permissions in groups etc) while other team can work on core domain which is creating/scheduling events with minimum/maximum number of users, signing up for events by users, canceling events etc). The only thing Events context need to know if particular user is in group or no and what permissions he has (can create events or just join them for example).
    – user606521
    Commented Dec 1, 2021 at 13:10
  • 1
    Again, I don't know all your use-cases therefore what trade-off is ideal. I'm just saying if service A sends events to service B for example, then you have a hard dependency. You will have coordination between teams, releases will potentially depend on the other service's release. That's all bad. Whether it is necessary or a good trade-off is up to you. But it is bad and you should try to avoid it if your use-case allows it. Commented Dec 1, 2021 at 13:20
  • 1
    Same if you need to do queries for data. Commented Dec 1, 2021 at 13:21
  • 1
    One of my current projects has multiple "services" because of different scalability requirements. They all have the concept of "users", however they do not even know each other. If the user presents a valid JWT token, they are a user. That's it. They don't receive nor generate any events. There is no reason to. The "user management" "service" doesn't interface at all with the other ones, it just generates a JWT token. That is of course just my use-case and may not apply to other ones. I'm just saying no, "users" does not have to be a common "hard" dependency. Commented Dec 1, 2021 at 15:09
  • 1
    Why not? Because you are creating a hard dependency, which costs a lot in the long term. I'm not saying I would never do that, but it would be pretty much last resort. For example are you sure everybody needs the "email" of a user? If not, why is it globally defined? And if it is used in one service only, why isn't it only there? And if it is used in multiple services, can you slice it differently so it isn't? Repeat for all data. Creating events like that is not much better than a shared table in a shared db. Commented Dec 1, 2021 at 19:36

Not the answer you're looking for? Browse other questions tagged or ask your own question.