Greenfield Development with CQRS and Windows Azure


Published on

You have the dream situation - the ability to create a brand new product from the ground up. You want it to be scalable, performant and easily updatable (since you're building in an incremental fashion). But since you're a start-up, you don't want to deal with the headache and costs of hosting. Well, one possibility is taking advantage of cloud platforms (Windows Azure, for instance) and architecting your system using a CQRS-style pattern. See how you can create a system patterned on CQRS in the cloud. We can take a look at a product I created (BrainCredits) and also see how others would take advantage of Azure services to create CQRS-patterned systems.

Published in: Technology
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Greenfield Development with CQRS and Windows Azure

  1. 1. Greenfield Development withCQRS and Windows Azure David Hoerster October 18, 2012
  2. 2. About MeC# MVP (since April 2011)Co-Founder of BrainCredits ( at AgileWaysPresident of the Pittsburgh .NET User Group( and organizer of PGHTechFestTwitter - @DavidHoersterBlog – –
  3. 3. GoalsWhat is CQRS?Why would you use it?BenefitsSome examplesUsing CQRS in Azure
  4. 4. What is CQRS?CommandQueryResponsibilitySegregationIs it a pattern or an architecture?
  5. 5. What is CQRS?Command Query Responsibility Segregation Based upon Bertrand Meyer‟s Command Query Separation (CQS) principle: “every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, asking a question should not change the answer” (Meyer) In essence, commands return acknowledgement; queries return data.
  6. 6. BackstoryGoals for Product Fast reads Scalable Handle, potentially, large volumes of requests Be able to change quickly Ability to track user in system and events that occur Easy to deploy, manage Inexpensive (FREE????)
  7. 7. BackstoryDecided to jump into cloud with Azure Scalability Deployment via VS2010 (Familiarity) Pretty inexpensive – no HW to manage BizSpark company (at the time) – Currently 1500 compute hours of small instance – 5 GB of SQL Azure – Small cache instance – 2 million transactions/mo – and more… But how to store data and design system?
  8. 8. Backstory I would recommend to start looking along the CQRS style of architectures - Rinat Abdullin Articles by Greg Young, Udi Dahan, J. Oliver, R. Abdullin
  9. 9. What is CQRS?Common Architecture Issues Business logic bleeds through layers Validation logic ends up everywhere Copy and Paste development Apps that cater to modification ops Leads to general complexity within tiersCQRS simplifies this with classesperforming specific duties (SRP)
  10. 10. Evolution of a System to CQRSSimple App (tightly coupled) Application Database
  11. 11. Evolution of a System to CQRSBreaking out business logic Application Business Logic DatabaseWriteData(string, string, int, bool, …) { }
  12. 12. Evolution of a System to CQRSIntroduce messaging MSG Application Business Service Database
  13. 13. Evolution of a System to CQRSQuery Side Client Command Side Data Requested/Returned Command Issued – ack/nack Repository Command Service Domain (ARs) Optional Event Handler Denormalizer Event Store Read Model Store
  14. 14. What is CQRS? Encapsulates business logic in the domain Allows you to model tasks instead of CRUD Allows for scalability very easily Can provide for fast reads at the „expense‟ of more expensive writes Once the data is read by the client, it‟s already old A system that is eventually consistent is usually acceptable EVENTUAL CONSISTENCY! – The read model for the system eventually is consistent
  15. 15. What is CQRS?Taking this further, CQRS describes apattern where Commands are messages (possibly asynchronous) Queries go against a read modelSince commands are returning void, itallows for the message to be transformedinto the read modelThis flips the conventional wisdom of fastwrites and slow reads
  16. 16. Demo Simple Console-based System
  17. 17. High-Level Code Walk-through ofCQRSCommandA message sent to tell the system to do somethingpublic class CreateReservation : CommandBase { public Guid ReservationId { get; set; } public String Name { get; set; } public Int32 NumberOfSeats { get; set; } public String DiscountCode { get; set; } }
  18. 18. High-Level Code Walk-through ofCQRSDomainYour system‟s business logic and raises eventspublic class Reservation : AggregateRootBase { public void CreateNewReservation(CreateReservation cmd) { //do some logic to figure out TotalCost ApplyEvent(new ReservationCreated() { ReservationId = cmd.ReservationId, ReservationMade = DateTime.UtcNow, NumberOfSeats = cmd.NumberOfSeats, SeatsReservedFor = cmd.Name, TotalCost = totalCost }); }
  19. 19. High-Level Code Walk-through ofCQRSEventsMessages raised by the domain stating thatsomething has been donepublic class ReservationCreated : EventBase { public Guid ReservationId { get; set; } public DateTime ReservationMade { get; set; } public Int32 NumberOfSeats { get; set; } public String SeatsReservedFor { get; set; } public Decimal TotalCost { get; set; }}
  20. 20. High-Level Code Walk-through ofCQRSEvent Handlers (Denormalizers)Persist event information to the read modelpublic void Handle(ReservationCreated theEvent) { var reservation = new Reservation() { IsDeleted = false, NumberOfSeats = theEvent.NumberOfSeats, ReservationId = theEvent.ReservationId, ReservationMade = theEvent.ReservationMade, SeatsReservedFor = theEvent.SeatsReservedFor, TotalCost = theEvent.TotalCost }; var repo = new ReservationRepository(); repo.CreateReservation(reservation);}
  21. 21. BenefitsGet all of the orders for user “David” in last30 days SalesOrderHeader (SalesLT) SalesOrderID RevisionNumber SalesOrderDetail (SalesLT) SalesOrderID SalesOrderDetailID OrderQty OrderDate ProductID DueDate Product (SalesLT) UnitPrice ShipDate ProductID UnitPriceDiscount Status Name LineTotal OnlineOrderFlag ProductNumber rowguid SalesOrderNumber Color ModifiedDate PurchaseOrderNumber StandardCost AccountNumber ListPrice CustomerID Size ShipToAddressID Weight BillToAddressID ProductCategoryID ShipMethod ProductModelID CreditCardApprovalCode SellStartDate SubTotal SellEndDate TaxAmt Freight Customer (SalesLT) ProductModel (SalesLT) ProductCategory (SalesLT) CustomerID ProductModelID ProductCategoryID NameStyle Name ParentProductCategoryID Title CatalogDescription Name FirstName rowguid rowguid MiddleName ModifiedDate ModifiedDate LastName Suffix CompanyName SalesPerson EmailAddress
  22. 22. BenefitsGet all the orders for user „David‟ in last 30days SELECT c.FirstName, c.MiddleName, c.LastName, soh.SalesOrderID, soh.OrderDate, sod.UnitPrice, sod.OrderQty, sod.LineTotal, p.Name as ProductName, p.Color, p.ProductNumber, pm.Name as ProductModel, pc.Name as ProductCategory, pcParent.Name as ProductParentCategory FROM SalesLT.Customer c INNER JOIN SalesLT.SalesOrderHeader soh ON c.CustomerID = soh.CustomerID INNER JOIN SalesLT.SalesOrderDetail sod ON soh.SalesOrderID = sod.SalesOrderID INNER JOIN SalesLT.Product p ON sod.ProductID = p.ProductID INNER JOIN SalesLT.ProductModel pm ON p.ProductModelID = pm.ProductModelID INNER JOIN SalesLT.ProductCategory pc ON p.ProductCategoryID = pc.ProductCategoryID INNER JOIN SalesLT.ProductCategory pcParent ON pc.ParentProductCategoryID = pcParent.ProductCategoryID WHERE c.FirstName = David AND soh.OrderDate > (GETDATE()-30)
  23. 23. BenefitsWouldn‟t it be great if it was something like? SELECT FirstName, MiddleName, LastName, SalesOrderID, OrderDat e, UnitPrice, OrderQty, LineTotal, ProductName, Color, Produ ctNumber, ProductModel, ProductCategory, ProductParentCa tegory FROM CustomerSales WHERE FirstName = David AND OrderDate > (GETDATE()-30)
  24. 24. Command Side Flow Event 1 Handler 1Command Domain Event 2 Handler 2 Read Model Event N Handler N
  25. 25. Read Side Flow Request for Data QueryRead Provider ClientModel (Repo/WCF DS/etc) DTO
  26. 26. Demo Moving CQRS to Azure
  27. 27. CQRS in the CloudHosting CQRS in AzureTypically, you‟d want 2 roles Web Role for the UI, which also performs querying Worker Role for the Command handlingBoth roles can scale out as much as needed Multiple web roles with a single worker role, or vice versa or both!
  28. 28. CQRS in AzureQuery Side Web Role Command Side Client Worker Role Command Service Repository Domain (ARs) SQL Azure or other Event Handler Repository Denormalizer Event Store Read Model Store Table Storage?
  29. 29. CQRS in the CloudHow do I issue commands from myweb role? Some typical solutions WCF service on the worker role side 3rd party service bus tool Use Azure storage features (blobs, queues, tables) All have advantages and disadvantages
  30. 30. CQRS in the CloudGeneral flow is this Web role issues a command by dropping it in a blob container (name is GUID). Command blob name is then dropped in a queue Worker role monitors queue for work When it finds a message in the queue, it grabs blob from storage based on id in queue message Deserializes command and then sends it through normal CQRS pipeline
  31. 31. CQRS in the Cloud Web Role Worker Role Blob Storage Queue CommandController Domain Handler Azure Table Storage Event(s)Repository Denormalizer Azure Sub-system Read Model
  32. 32. CQRS in the CloudWeb and Worker Role Separation Share knowledge of queues and interfaceIf worker were to go down, web would stillrun Commands would queue up Provides some level of fault tolerance
  33. 33. CQRS in the CloudWorker role can spawn multiple threads tomonitor queues BrainCredits has several threads CommandQueue and LogQueue Different polling intervals Depending on importance of information
  34. 34. CQRS in the CloudUsing Azure Table Storage for logging useractions… Different than events. Want to know user behavior. Storage is huge – just watch transaction costs Consider batching log reads But you can create replays of user interaction Similar to event sourcing‟s replay of events Event sourcing doesn‟t capture “Cancels” or “Reads”, which may be useful from a marketing perspective
  35. 35. Claim Credit for this SessionBrainCredits
  36. 36. ResourcesCerebrata Cloud Storage Studio – http://cerebrata.comParaleap AzureWatch – http://paraleap.comConference Reservation Example on GitHub Journey – Info Site – Google Group - Dahan’s CQRS article “Clarified CQRS” – Abdullin’s CQRS information – Podcast -