Good content. One of the big pitfalls is; this approach should separate representations of the "Catalog" for model, DB and http/json independently, which people tend to quickly abandon, as it is seen as triplicates in the beginning and by the time it is realized it should have been separated, it is often really difficult to break things apart. And this goes for CQRS and Event Sourcing styles as well... Making good system requires discipline.
Thanks, @niclash. Do you think that is missing from the tutorial? I thought I covered those points. If you think your concerns are missing I'd like to address them somehow.
@@Vaughn_Vernon Well, you describe file structure and put all packages under src/main/ and don't touch on the risk of contamination (a.k.a spaghetti) between packages in the wrong directions. Very good discipline and certain analytics tools can keep it "right", but from experience it is a battle that will eventually be lost. Hence, I typically advocate for breaking out into separate projects, where Maven/Gradle will prevent the cyclic dependencies that we don't want.
Sir, It was great explanation, based on user role, we can return different Read Models of Catalog domain Entity or Aggregate, am I understand correctly?
Nice one, thanks Vaughn. Though a question here. What is exactly Catalog component? Is it a stateful domain object or something else like domain service? And if it is a domain object then why does it contain query methods?
It's something in the model. What it is isn't important. There's nothing wrong with whatever it is having a query method, but don't take the example too seriously. It's reused from Part 1, and I quickly introduced an Application Service as a Port to show that possible aspect.
P&A is so simple and simple is good. There is an unnecessary complication which introduces more impurity to the model and I'll explain. The CatalogueService being an interface "because it has to support transactions and access control". Consider this: the user wants to accomplish a goal when he accesses the controller. The user doesn't care about partially done work, it's all or nothing. Eventual consistency aside, not the case for this scenario in an e-commerce application. So the transactional boundary can be in the controller, together with all other technology-centric concerns. The Service is just telling the controller if it's done his job successfully or not, and based on that the controller can do a commit or a rollback. Now, in reality you wouldn't have to do this in each controller, but instead you can have a Middleware further to the outside doing commit or rollback across any repository and controller operations. As for permissions, I like what you've done there with the Catalogue being an interface and the various implementations in the different (or not different) bounded contexts. It's a neat idea, but I wouldn't leverage it to do access control. Instead, I'd push this concern further out: the UI knows what roles the user has, and it can render calls to completely different endpoints to do the other operation. This greatly reduces the number of ifs on the inside. Polymorphic calls are also ifs. I mean, the UI most likely already has the if there in order to do some things differently based on the role. Yes, you still need a check for the role in the backend, but that can be unambiguously be applied to the (now two) endpoints in the controller. We're always going to have different views on these questions, but regardless of that, P&A leads to a clean and simple separation of an inside and an outside. So thank you for the material.
I was about to comment and saw this, I agree with the permissions part, I don’t think that level of abstraction is needed if you move the responsibility up, either to the UI or a separated flow or even a module, a content manager and a consumer have completely different needs in a system. Separating it would make everything much simpler and less abstract.
I've demonstrated concepts, not working code, and I haven't made a single recommendation other than the large concepts. I say several times, you could do this or you could do that ("that's one way to do that"). Look at the architectural principles.
I'm sorry, but this explanation is totally unclear. Even though I'm familiar with P&O, this vague explanation feels like Microsoft presenting JScript while everyone else is speaking JavaScript.
The recording is so good I can see sharp :)
Good content. One of the big pitfalls is; this approach should separate representations of the "Catalog" for model, DB and http/json independently, which people tend to quickly abandon, as it is seen as triplicates in the beginning and by the time it is realized it should have been separated, it is often really difficult to break things apart. And this goes for CQRS and Event Sourcing styles as well... Making good system requires discipline.
Thanks, @niclash. Do you think that is missing from the tutorial? I thought I covered those points. If you think your concerns are missing I'd like to address them somehow.
@@Vaughn_Vernon Well, you describe file structure and put all packages under src/main/ and don't touch on the risk of contamination (a.k.a spaghetti) between packages in the wrong directions.
Very good discipline and certain analytics tools can keep it "right", but from experience it is a battle that will eventually be lost. Hence, I typically advocate for breaking out into separate projects, where Maven/Gradle will prevent the cyclic dependencies that we don't want.
Sir, It was great explanation, based on user role, we can return different Read Models of Catalog domain Entity or Aggregate, am I understand correctly?
Thanks! There are no separate write and read models. This is not attempting to explain or even allude to CQRS. So it's just a query on the model.
Nice one, thanks Vaughn. Though a question here. What is exactly Catalog component? Is it a stateful domain object or something else like domain service? And if it is a domain object then why does it contain query methods?
It's something in the model. What it is isn't important. There's nothing wrong with whatever it is having a query method, but don't take the example too seriously. It's reused from Part 1, and I quickly introduced an Application Service as a Port to show that possible aspect.
@@VaughnVernon Thanks for the reply
Thanks for this!
Just one question, would the CatalogService implemented in the inside and injected into the CatalogController in this example?
Yes, probably. You must have missed my explanation of using main(). I use the upper right corner of the diagram surface.
@@VaughnVernonPerfect! just wanted to confirm the implementation. The tutorial was awesome, thank you so much!
P&A is so simple and simple is good.
There is an unnecessary complication which introduces more impurity to the model and I'll explain.
The CatalogueService being an interface "because it has to support transactions and access control".
Consider this: the user wants to accomplish a goal when he accesses the controller. The user doesn't care about partially done work, it's all or nothing. Eventual consistency aside, not the case for this scenario in an e-commerce application.
So the transactional boundary can be in the controller, together with all other technology-centric concerns.
The Service is just telling the controller if it's done his job successfully or not, and based on that the controller can do a commit or a rollback.
Now, in reality you wouldn't have to do this in each controller, but instead you can have a Middleware further to the outside doing commit or rollback across any repository and controller operations.
As for permissions, I like what you've done there with the Catalogue being an interface and the various implementations in the different (or not different) bounded contexts. It's a neat idea, but I wouldn't leverage it to do access control.
Instead, I'd push this concern further out: the UI knows what roles the user has, and it can render calls to completely different endpoints to do the other operation. This greatly reduces the number of ifs on the inside. Polymorphic calls are also ifs.
I mean, the UI most likely already has the if there in order to do some things differently based on the role.
Yes, you still need a check for the role in the backend, but that can be unambiguously be applied to the (now two) endpoints in the controller.
We're always going to have different views on these questions, but regardless of that, P&A leads to a clean and simple separation of an inside and an outside.
So thank you for the material.
What about if a user should be able to only view the catalog, not edit. Another different endpoint?
@@z0nxare we talking REST?
I was about to comment and saw this, I agree with the permissions part, I don’t think that level of abstraction is needed if you move the responsibility up, either to the UI or a separated flow or even a module, a content manager and a consumer have completely different needs in a system.
Separating it would make everything much simpler and less abstract.
The controller/adapter can have multiple request handlers. Be sure to watch Part 1 or you won't get the complete picture.
I've demonstrated concepts, not working code, and I haven't made a single recommendation other than the large concepts. I say several times, you could do this or you could do that ("that's one way to do that"). Look at the architectural principles.
(y)
I'm sorry, but this explanation is totally unclear. Even though I'm familiar with P&O, this vague explanation feels like Microsoft presenting JScript while everyone else is speaking JavaScript.