Giter Site home page Giter Site logo

mauroservienti / all-our-aggregates-are-wrong-demos Goto Github PK

View Code? Open in Web Editor NEW
219.0 219.0 38.0 1011 KB

A microservices powered e-commerce shopping cart sample - based on SOA principles. Demos and sample for my "All our Aggregates are Wrong" talk

Home Page: https://milestone.topics.it/talks/all-our-aggregates-are-wrong.html

License: MIT License

C# 92.50% CSS 1.37% JavaScript 0.04% HTML 5.93% TSQL 0.16%
aggregates ddd demos hacktoberfest nservicebus samples soa talks viewmodel-composition

all-our-aggregates-are-wrong-demos's Introduction

Who I am

Mauro is a Solution Architect in Particular Software, the makers of NServiceBus. He spends his time helping developers building better .NET systems leveraging Service Oriented Architecture (SOA) principles and message-based architectures.

When he is not busy with distributed systems he loves to go back to one of his first loves: rich client development using XAML based technologies. Mauro usually writes about technology, but not only, on his English blog at //milestone.topics.it and his Italian blog at //blogs.ugidotnet.org/topics. He is also passionate about skiing, road bike riding, swimming, classical dance, and music, in general.

Latest blog posts

all-our-aggregates-are-wrong-demos's People

Contributors

adamralph avatar deep145757 avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar github-actions[bot] avatar mauroservienti avatar vaibhav-009 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

all-our-aggregates-are-wrong-demos's Issues

Dealing with order in ViewModel composition

@mauroservienti Looking at CartIdAppender it seems like it must be run before other IHandleRequests or the cart-id cookie may not exist, and operations may fail. However I don't see this being dealt with anywhere. Is there a strategy for dealing with this?

Do the demo's service API projects require NSB endpoints?

Do API projects in the demo, such as Sales.Api, require an NSB endpoint registration such as shown here?

I thought the intention of these projects was merely to surface data through GET requests initiated from the services viewmodel composition project. If so then there's no need for an endpoint, or am I missing something?

Question: If Shipping had a cost requirement which service owns that price?

Sales appears to own each product's price. If Shipping had a cost associated to each ProductShippingOptionsId would Sales also own that price? My assumptions here are that Sales should own all pricing data, is that wrong to assume?

For example, as a user decides on their required shipping option, after checkout I'm assuming, Sales updates its Order to include new order delivery information, i.e. current option and current price.

If we were to take this a little further and talk about discounts, does Sales also own the how and when the discounts are applied but not necessarily "if" the discounts are applied?

My thinking is in terms of Udi's video talks around Engine Patterns and how he describes a discounting pipeline where other components contribute their own decisions about how much of a discount is applied. So, in our current Sales and Shipping scenario, Sales would trigger (in memory) a discount engine on checkout, and the engine would compose the available discount components (from other services) and execute their logic.

An example of the logic for Shipping might be to track numbers of deliveries per month and give a discount for over 10. I feel shipping owns this logic and the percentage/fixed delivery discount, but not the original delivery (base) price. I'd be interested in your thoughts please.

How to handle change of cart item quantity?

I've noticed the AddItemToCartHandler (in sales) adds a new ShoppingCartItem for the given request, including the user-selected quantity. So if a user adds the same product again (new POST request) they would end up with 2 cart items, one each for the same product.

I assume that's why the GetCart controller method in sales returns an aggregation of quantity and price grouped around the ProductId? This also means the user would see a list of individual products with a single quantity and price. All good and fits the user expectation I imagine.

Removing a product from the cart entirely could be handled by deleting all cart items with a matching product id. How would you handle a use case where a user wants to change the quantity of an existing product in the cart?

[QUESTION] How to implement an archiving service for order history?

My apologies @mauroservienti if this is an inappropriate place to ask this question. Please let me know where would be a better forum.

I have watched this repository's related YouTube videos with specific interest around the question at https://youtu.be/KkzvQSuYd5I?t=2621. Your answer describes a separate service generating a PDF invoice using appenders to compose the data (view model) to use in a template, the service then persisting the PDF for later client retrieval.

I mention this use case as I think it might be how I would solve the following requirement but I'm not entirely certain.

The System

So lets say I have a set of services such as in your repository that facilitate an ecommerce mobile application. The services are deployed in 2 cloud regions, one in the US and one in Europe. Customers in each region's country are routed to the nearest region. There is no data replication between the regions. They are effectively two different ecommerce shops with their own products for sale.

The Requirement

Customers can travel to both the US and Europe and so can make purchases from both regions under the same identity. A customer signed into a mobile app using the one identity should be able to see their global order history (receipts) no matter what region their mobile is routing to.

The Problem

If each region has data isolation then no one region has a view of all orders made by a customer globally.

A Possible Solution?

Each region should have an OrderHistory service that can listen for OrderCompleted events from Sales to trigger an ArchiveOrder command. The command handler would use appenders (supplied by the Sales, Marketing, etc) to obtain a model of data to store as an archive record. After persistence it could publish an OrderArchived event letting the other services know they can delete their CartId related data.

The backing store of the OrderHistory service could be a globally-available store such as CosmosDb or MongoDb where each region's service uses the same database. No matter the region routed to from the mobile app when viewing order history, the same combined dataset is surfaced to the customer.

This has the added benefit of limiting data in the other services to only those orders that are not complete.

Does this sound like an appropriate solution without breaking SOA principles? Or do you see simpler alternatives?

Again, apologies if not the place for this question.

Stop using HTTP from IHandleRequests implementations

Currently IHandleRequests implementations use HTTP to talk to their back-end services. That's not needed, and lead to confusion. It leads people to believe they must use HTTP, but in reality since they logically belong to a service they can easily access service data directly.

Can't find an example with CleanupFailedCartRequest

Can you pls show how to compensate in case on of the handlers fail to process the request? What would be the valid reason to fail? business exception? Request contains invalid data? Or should we strive to make sure our command is valid in 99% and dont perform any compensation requests?

add item to cart error handling IHandleRequestsErrors

Let’s say adding an item to a cart failed in the sales handler (ShoppingCartAddPostHandler).
And the server goes down, iis reset, whatever just before OnRequestError was able to do its work?

CleanupFailedCartRequestHandler in Shipping will never get notified that something went wrong and will be in an incorrect state.

Or did I miss something? Why not send events from the sales domain after the shopping cart has been saved successfully?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.