I have to develop an eCommerce website following DDD.
I just completed Ardalis and Julie DDD pluralsight course and need to come up with bounded-context for this project.
Can you please assist if I properly identify bounded contexts for this project?
The requirement is as follow :
The system has 3 types of users : Admin, Manager, and Customer
The system needs to record products, then will display them on online listing,
customer users needs to be able to log invoice which must contain : products added to the invoice + the total
Manager user must be able to edit all invoice.
System must have report on all product sold, in-stock, total products
System must have notification sent to managers only about products that need to be replenished.
I'm thinking of creating 3 bounded context as follow :
Product Management (record, list, invoicing)
For me, Invoice should be a value-object as it doesn't make sense alone, it has always to be associated with customer user.
Report Management
User Management (Admin, Manager, Customer)
Regarding notification, I'm gonna just use Domain Event, no need for a specific bounded-context for it.
Related
I want to create a website for selling and buying stuff. When a user offers to buy a product and the seller accepts the offer is getting a notification that the product is sold to him and the product's status is changed to sold. How would one visualize this with domain storytelling?
Currently, my story looks like this but I don't like how the notification looks like it comes from the seller but the seller doesn't do anything because the notification is sent automatically and not sent directly by the seller. Same problem for the status of the product.
There are two ready options:
You can view the story as saying that the offer updates the status and sends the notification
You can explicitly model that there's some process (I've seen gear icons used to denote this) watching for accepted offers and updating the status and another (or possibly the same, though beware of multiple changes in one process) process watching for accepted offers and sending the notification
I have product service, category service, promotions service, search service.
When User want to add product. CreateProductRequest come to product service. Request includes product data and datas of other services like categoryId,uncalculated price , too. After product is added. I need to send other servie datas. Category service needs productId and CategoryId. Promotions service needs productId and price.
After creat eproduct transaction commited;
1) I put all data in ProductCreatedEvent that includes saved productId, categoryId, uncalculated price etc. Every service get what it needs from event and save to own db. I publish event with RabbitMQ
2) Send via seperated commands to services.I send commands with RabbitMQ
And What If there is no category that id come with event and Category services didn't save. But Product saved at product Services ?
or what do you suggest ?
To answer the question, it's important to keep in mind the difference between a command and event. A command is a request to do something. An event is a record of something that has happened. One key difference is that a command can be rejected.
When looking at your use case, publishing events to other services makes the most sense. The product has been created and you are notifying the other bounded contexts that care about the change. If you issue a command, you are telling other bounded context to make a change that may or may not fail.
That said, you each bounded context may receive the event and produce a command within their own context to update aggregates managed within. As such, the difference is subtle between these two:
- Issue a command to each bounded context
- Issue an event to each bounded context and they can then trigger a command as needed
But given the above, the notification of the creation of the product should not fail. It has happened already. From there, each context can decide what to do about it.
I am wondering how to keep track of the owners assets. I don't think having an asset called 'stock' would be very effective in this regard, because that would not seem like the blockchain way.
Let say you are sending a shipment with Product asset to another owner. This owner needs to accept the shipment of products. When he accepted it should I add these products to an inventory asset of that owner?
The other option is when the new owner accepted the shipment, do nothing. And when the owner wants to know his inventory he queries all the shipments with his signature to get the ID of the assets he owns.
I suggest you reading the official Commercial Paper Tutorial which is similar to what you're trying to do.
https://hyperledger-fabric.readthedocs.io/en/release-1.4/tutorial/commercial_paper.html#
I am designing an Ecommerce using micro services architecture. Suppose that I have two context a product catalog, inventory and pricing.
It's seems clear to me that they have a clear responsibility. But to serve the show case (the product list) I need to make a request for the product catalog, get a list of ID's and then use it to query the Inventory micro services to check inventory status ( in stock or stockout). Besides that I need to make a request to Pricing to get the price of each product.
So basically to serve a fundamental feature makes me execute three requests (like a join) in three micro services. I have been reading about micro services architecture and when you are dealing with many "joins" it's possible that the these contexts should be a single one. But, IMO it seems clear to me that each context has a different set of responsibilities.
The other option is to create a "search" micro service that aggregate all these information (product + pricing + inventory). We can use a domain event to notify "search" microsecond that something has changed. So we can resolve show case with a single request. This look like a CQRS.
The question is...
Is there a correct approach?
Which one is better ? Trade-offs?
you can try to include some information from different domain contexts to other domain context
so you product catalog domain will contain #of items , price from inventory and pricing domains.
This will be a read only (value objects)and should be updated by events from inventory and pricing domains .
in your use case the trusted source of truth will be carried in inventory domain so if any synchronization failure happen still the inventory will reject any order because of availability .
in your case i think its better to create a separate search microservice to aggregate the data from all of them as search is mostly always from multiple domain areas like product , inventory and ....
and you can use events from other microservice (Event Sorucing) to populate the data in search.
It seems that what you need is to show in a view info coming from different microservices (contexts).
You can use ViewModel Composition technic, where an infraestructure component (a request handler) intercepts the http request and allows microservices to participate in the response, looking for a microservice who says "hey, I have that info" (Inventory has the info about stock, Pricing about price, and so on). This infraestructure component compose a dynamic viewmodel on the fly, with the info coming from differect microservices.
I've never implemented it, but look at this video explaining it, from minute 17:35 to 21:00
https://www.youtube.com/watch?v=KkzvQSuYd5I
Hope it helps.
Update on 14-Feb-2019
Probably this will answer your question in more detail https://stackoverflow.com/a/54676222/1235935
I think the right approach here is to use Event Sourcing to pre-aggregate the show case data with product description, inventory and price. A separate microservice is probably not needed. This pre-aggregated data (a.k.a. materialized view) can be stored in the same microservice that handles the user request to display products (probably the order creation service).
The events could be generated by log-based Change Data Capture (CDC) from the DB of the product, inventory and pricing services and writing them to their respective topics in a log structured streaming platform (e.g. Kafka or AWS Kinesis) as mentioned here. This will also ensure "read your own write" guarantees in product, inventory and pricing services
I'm building a e-commerce with DDD and Event Sourcing, CQRS. My ideia is separate each AR in a microservice.
In my AR ShoppingCart I need a VO Item with productId and a Price, because price doesn't change after add to the cart.
I have another AR Product that control the price.
My problem is, how get the Price from AR Product without a synchronous request to the Product since I'm using a event architecture?
Fundamentally, what you are trying to do is copy information from one aggregate root to the other.
There are two approaches you might take.
One is to think in terms of a cache - we pass to the shopping cart an instance of a domain service that knows how to take a correlation id (product code?) and get a cached copy of a price. So we have a background process that copies pricing information from the pricing micro service to the shopping cart micro service, and then the autonomous shopping cart relies on its locally cached copy of the price.
Important note: there's nothing wrong with including timeliness metadata in the cache, so that the sharping cart can include intelligence about whether or not the cached information is "too old".
The other is more direct - have a method by which you can send a command with the price to the shopping cart, and build some orchestration logic that observes which shopping carts need prices, then send send a command to the cart with the appropriate price.
If you have two microservices, you can have each microservice publish a stream of events. Your ShoppingCart microservice can consume PriceChanged events from your Product microservice and maintain a local cache of the last price per Product. When you add a Product to a ShoppingCart, you would reference the local cache of prices.
This same approach of listening to events as a means of communication scales up from inter-Aggregate to inter-BoundedContext or inter-Microservice and even inter-System. Depending on your sensitivity to price changes, you might have to employ other approaches as described, but I assume you have some tolerance to eventual consistency given your choice in the CQRS+ES pattern.