No video

Defining Service Boundaries by Splitting Entities

  Рет қаралды 8,430

CodeOpinion

CodeOpinion

Күн бұрын

Пікірлер: 53
@argentum_serebro
@argentum_serebro 3 жыл бұрын
I just can't stop watching your videos. Pure gold.
@CodeOpinion
@CodeOpinion 3 жыл бұрын
Hopefully they are helpful
@bahtiyarozdere9303
@bahtiyarozdere9303 3 жыл бұрын
This is one of the greatest videos I have ever watched about software architecture. Simple and effective. Thank you sir!
@allannielsen4752
@allannielsen4752 3 жыл бұрын
Great video, this is sort of a precursor to where we are now. We stopped using the term Entity and instead implement a model we call a Concept (same as you said numerous times). A concept is a concrete class that defines the unique attributes and rules around an entity (i.e. a Product SKU). In your example "product = Concept" whereby the class defines key(s) and rules that may go around those keys. So instead of saying a productId = Guid, the SKU then becomes the product concept. Every other property (Attribute) then becomes an extension of the domain feature being implemented in whichever boundary it is (i.e. Sale Product has Price). Hope that makes sense. What this has done in our design and development has been amazing and we no longer see these huge bloated Entities, but instead we have slim defined and agreed "process models" that use a Concept thereby always talking the same type. Bottom line (rule) - All entity types can not use primitive(s) as a key, they must be a Concept.
@CodeOpinion
@CodeOpinion 3 жыл бұрын
Interesting. Any chance you could provide a gist to give as an example?
@allannielsen4752
@allannielsen4752 3 жыл бұрын
@@CodeOpinion better yet, we used the /Source/Concepts from dolittle as a basis (github.com/dolittle/DotNET.Fundamentals). Sorry I can't share our implementation, but this was our starting point. The world of Dolittle is an interesting one (I have no affiliation with them though).
@CodeOpinion
@CodeOpinion 3 жыл бұрын
Thanks, I'll take a look.
@sampsonorson
@sampsonorson 3 жыл бұрын
Thanks for another great video.
@MrAlielsonPiffer
@MrAlielsonPiffer 3 жыл бұрын
Maybe I'm missing something, but if some client consumer requires a list of sales and each item must contain the price and name of the product, how should I join this information? Should Sales context get extra info from some service or repository in another context (coupling again?) or should the client do another request?
@CodeOpinion
@CodeOpinion 3 жыл бұрын
Sales can have the product name, even if it doesn't own it. Basically a local cache used for these purposes. However just be aware that it's read-only/cached and not the point of truth.
@srik790
@srik790 3 жыл бұрын
Thanks for coming up with another great video... I have a question... I understand splitting up entity but how the ui/ux will to create product model from user perspective as now it is spread to different boundaries. And what if sales doesn't have that product definition yet..while purchase product
@CodeOpinion
@CodeOpinion 3 жыл бұрын
Depends on what the UI needs to be. It's really about where do you want to do the composition. If you're talking about a SPA that's interacting with an HTTP API, you could either compose in the frontend by having components owned by each boundary (calling multiple different HTTP APIs for each context). Or you could do the composition on the server to return a unified model.
@kasunjalitha2300
@kasunjalitha2300 7 ай бұрын
@@CodeOpinion But what If one call fails? All other contexts will create its own object and persist in their own database. But one context will miss that part. Isn't it?
@ItsJustEza
@ItsJustEza 3 жыл бұрын
I just stumbled across this video and found it quite good. I had a question: so here you are splitting up the entity properties in the application but would they still reside in a single table in the database? Or would you split up the table in a similar fashion to the way the entity classes were split up in the application?
@CodeOpinion
@CodeOpinion 3 жыл бұрын
In my example I use with this Loosely Coupled Monolith, each boundary/context has it's own database. So to answer your question, they would be physically be different databases/tables. That's not to say you couldn't make it more of a logical separation and use the same table, but that might be more difficult to maintain from a developer point of view to make sure no context is using the fields/columns from another context.
@ItsJustEza
@ItsJustEza 3 жыл бұрын
@@CodeOpinion Thanks, I'll have to go through your other videos about the loosely coupled monolith to better understand how and why you have it set up in this way.
@Stap1223
@Stap1223 3 жыл бұрын
If you maintained it as a single context you'd probably have to duplicate the entity classes with ALL the properties on them from across the bounded contexts and use those entities in a separate project for maintaining migrations with EF Core. That would be a pain from a development point of view due to needing to copy the changes into a second class all the time. I guess the benefits of this would be price in terms of paying for a single database vs multiple databases if you're using something like Azure SQL for hosting.
@iandrake4683
@iandrake4683 3 жыл бұрын
@@CodeOpinion if I understand you correctly, the product entity maybe divided across multiple tables or databases. So, if "cost" and "price" are essentially the same data, but viewed (and named) from different contexts, then does that mean you would store that value in multiple tables despite that it should always be the same value?
@CodeOpinion
@CodeOpinion 3 жыл бұрын
@@iandrake4683 no, price and cost are not the same. Price I sales is the sale price to customers. Cost is the purchase price from vendors.
@thomasjardanedeoliveirabou9993
@thomasjardanedeoliveirabou9993 Жыл бұрын
I really like this concept, I just dont understand how i would create an full entity. For example, if i have an product like you described, with all properties as not nullable, there would have to be an service that has the full entity defined so i could create it, and that undermines the whole coupling problem we were trying to solve. Am i missing something? I hope I am, i really like this approach.
@CodeOpinion
@CodeOpinion Жыл бұрын
There is no "full" entity. Each logical boundary has it's concept of that entity. This is a much longer video but will better explain: kzbin.info/www/bejne/gmO6n6RmeM10f6M
@Cypressious
@Cypressious 3 жыл бұрын
Very interesting video. I assume this concept can be applied to both, a monolith and a micro service architecture. The representations of the entity can live in different tables of the same database or in different services.
@CodeOpinion
@CodeOpinion 3 жыл бұрын
Exactly. This applies to both a monolith or (micro)services.
@JonSommervold
@JonSommervold Жыл бұрын
Thanks for another superb video!! Allthough it’s been a couple of years, I think it’s still highly relevant. Most likely these data (some or all) has to be combined so they can be presented together in the UI. I would be most grateful if you could make a video where you elaborate on the pros and cons of of doing this at the client as opposed to the serverside (in a BFF/gateway?). Or does such a video exist in you vast library allready??
@CodeOpinion
@CodeOpinion Жыл бұрын
Check out this video about UI and ViewModel Composition: kzbin.info/www/bejne/f33Fm36IZquLpcU
@JonSommervold
@JonSommervold Жыл бұрын
Thanks a lot for the link! I will watch it asap! 😃
@ddanielsandberg
@ddanielsandberg 3 жыл бұрын
Udi Dahan would be proud if he saw your videos. :)
@CodeOpinion
@CodeOpinion 3 жыл бұрын
Udi's talks have definitely had an influence on my thinking.
@Galakyllz
@Galakyllz 2 жыл бұрын
What are your thoughts on a separate project/library that performs the db queries? Each project that needs to communicate with the database depends on that project/library. So the projects depend on the db library and the db library depends on the database. The goal is to remove the strong dependency from each project on the database so that a database change to the Product table does not cause changes in many other project, just the one db library. Thoughts?
@CodeOpinion
@CodeOpinion 2 жыл бұрын
I'm a fan of Vertical Slice Architecture that focus and organizes code by features rather than technical concerns. Check out this video as it might help answer your question: kzbin.info/www/bejne/mYe5fpWrgNKBm9U
@drewjaqua2905
@drewjaqua2905 2 жыл бұрын
Is your motivation to split ProductModel into different contexts related to the Single Responsibility Principle as Robert Martin explains in Clean Architecture? Also, is this what Martin Fowler refers to as a "Bounded Context"? Sorry if these questions seem annoyingly n00bish ... I'm still learning about this stuff and trying to build a working model of all these terms and paradigms in my mind!
@CodeOpinion
@CodeOpinion 2 жыл бұрын
Bounded Context which is from Eric Evans' Domain Driven Design book.
@drewjaqua2905
@drewjaqua2905 2 жыл бұрын
@@CodeOpinion I saw where Martin Fowler cited that book a few times, went to buy it, but some of the reviews scared me @ the price. Do you recommend it?
@bunnihilator
@bunnihilator 2 жыл бұрын
when "creating" a product, how should these attributes be provided and how is it distributed for each bounded context. is there a central point for receiving all product attributes? or should we register the product multiple times for each boundary?
@CodeOpinion
@CodeOpinion 2 жыл бұрын
Any given boundary can "create" a product. But likely whoever owns the SKU, since that's what is shared to identify the product would be the primary starting point. It could publish an event that other boundaries would consume to know that product exists.
@sorteslyngel2k
@sorteslyngel2k 2 жыл бұрын
If an entity exist under several domains but they all share an ID, doesn't that mean you would need some kind of orchestration to define the ID to make sure it is the same ID across different boundries?
@CodeOpinion
@CodeOpinion 2 жыл бұрын
It's going to originate from a single boundary so you can propagate via events for other boundaries if needed.
@dttah
@dttah 3 жыл бұрын
Hey Derek, Great Video. I have some questions. I have heard udi dahan speak about splitting an entity this way. He went one step further to say even when raising domain events. As an example StockAddedToWarehouse, you wouldn't share the context's business data or you will be creating coupling via the event. You also speak about thin events. I was wondering though In this video in the example about ATP, you are essentially sharing business data. Like event carried state transfer, so doesn't that create a form of coupling? If tomorrow you decided to change your bounded context because of requirments, Wouldn't your sales context be coupled to that event via naming and that it expects that property to exist on that particularly named event. Next question, when data is split up this way, how do you do reporting? You would have to do something like hydrating some state somewhere else through events or something or some sort of orchestrator to do all the rpc calls? The first one although nicely decoupled creates that coupling again and the second solution has temporal coupling. Thirdly. When is splitting up your entity's properties relationship to one another going too far? Your example is great because each field is a sort of a complex business field but lets take abook entity. You have title dateCreated and quantity. Quantity could be it's own bounded context because their might be complex rules on it and it doesn't relate to title or dateCreated. DateCreated and title don't relate to one another and they not really complex enough to warrant a service on there own. Is the question you ask yourself well logically these two fields gotogether because they don't really have compelx logic acting on either field individually, they not directly related to one another but logically it makes sense to be here and decomposing it further seems like waste?
@CodeOpinion
@CodeOpinion 3 жыл бұрын
Thanks for the comment. Some of this is related to a video I'm hoping to do in the future about inside vs outside events. Core domain events are usually pretty stable. Meaning they won't likely change as you may choose to expose those to other services instead of creating an integration event. So when you said "As an example StockAddedToWarehouse, you wouldn't share the context's business data or you will be creating coupling via the event.". Yes, you're going to couple on on the schema of the message. You have the expectation that event is being published and the shape of it. As for reporting, it depends on how realtime/stale the data can be your using for "reporting". Ultimately it's just a cache. Do you want to do Event Carried State Transfer or prefer to use events as notifications so you can query the publisher for the data you need to update your local cache. Check out my video on RPC vs Messaging and where its origination from. kzbin.info/www/bejne/gn6uh62dqs15rZY Regarding splitting entities, yes the question should be do these things change together? Does the underlying data change from exposed behavior/capabilities within that service.
@tuberklz
@tuberklz 3 жыл бұрын
Thanks for your efforts on sharing your experience. Would you please also be kind enough to share which vs extension automatically provides types of variables that you use as you code along in a way that types are defined in typescript?
@CodeOpinion
@CodeOpinion 3 жыл бұрын
I'm using JetBrains Rider as my IDE. www.jetbrains.com/rider/
@alancastro383
@alancastro383 3 жыл бұрын
If you have a pretty big bounded context, would you organize it the same way?
@CodeOpinion
@CodeOpinion 3 жыл бұрын
I generally organize code by feature. Check out the video I did on this: kzbin.info/www/bejne/hoPRpGOoprWipKM
@thedacian123
@thedacian123 2 жыл бұрын
Hello, So one entity migth leave in my bounded context so many data stores, since each bounded context has each fata store, the only link between all these would be the entity Id ,right,wich must be the same in all boundries.Is this correct?Thnks
@CodeOpinion
@CodeOpinion 2 жыл бұрын
Correct. The concept of an entity might live in different boundaries but share some identifier that correlates them
@srik790
@srik790 3 жыл бұрын
What are hosting option on Azure Paas and CI/CD as now it has two processes.... .netcore web app and worker...
@CodeOpinion
@CodeOpinion 3 жыл бұрын
Great question! So deployment in general is a matter of deploying both processes since they ultimately are using the same codebase. The only time I've run into issues with this is generally around messaging. For example lets say you change an event to include a new property. If you're doing a rolling deployment and WebHost process on version 1 publishes the event, and the Worker is on version 2 and expects that new property that's not set. This is easy enough to overcome with versioning messages, but it's generally around points in time where there's some interaction between both processes via messaging.
@cosorxndrw
@cosorxndrw Жыл бұрын
You're taking simple ideas, implementing them into an oversimplified project, but this will very rarely happen in a real world project.
@saurabhchauhan232
@saurabhchauhan232 3 жыл бұрын
would be nice if you share your thoughts with DDD and No Sql
@CodeOpinion
@CodeOpinion 3 жыл бұрын
Good idea!
@Mvision123
@Mvision123 3 жыл бұрын
Do you treat the id as the sku in real world apps?
@CodeOpinion
@CodeOpinion 3 жыл бұрын
ProductId wouldn't likely be the product ID. It would likely be the SKU. Not a GUID or primitive.
Scaling Monolithic Applications
8:48
CodeOpinion
Рет қаралды 6 М.
Is a REST API with CQRS Possible?
16:46
CodeOpinion
Рет қаралды 35 М.
123 GO! Houseによる偽の舌ドッキリ 😂👅
00:20
123 GO! HOUSE Japanese
Рет қаралды 4,9 МЛН
Thin or Fat Events? Are your boundaries right?
7:25
CodeOpinion
Рет қаралды 7 М.
AVOID Entity Services by Focusing on Capabilities
7:31
CodeOpinion
Рет қаралды 31 М.
START with a Monolith, NOT Microservices
8:07
CodeOpinion
Рет қаралды 19 М.
My TOP Patterns for Event Driven Architecture
10:45
CodeOpinion
Рет қаралды 30 М.
BEYOND Status Codes! Better REST HTTP API Error Responses
7:52
CodeOpinion
Рет қаралды 17 М.
SOLID Principles? Nope, just Coupling and Cohesion
13:56
CodeOpinion
Рет қаралды 32 М.
Keep your project structure simple!
15:08
CodeOpinion
Рет қаралды 17 М.