Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

CQRS in 4 steps

206 views

Published on


This is a presentation how to introduce CQRS pattern to an existing application, step by step, without breaking changes and holding up the development.

Published in: Internet
  • Be the first to comment

CQRS in 4 steps

  1. 1. 11 CQRS IN 4 STEPS
  2. 2. 22 radblog.pl @RadekMaziarkaobjectivity.co.uk Radek Maziarka http://radblog.pl/CQRS
  3. 3. 33 CQRS Command Query Responsibility Segregation
  4. 4. 44 BUILDING BLOCKS
  5. 5. 55 WHY YOU SHOULD EVEN CARE?
  6. 6. 66 INITIAL STATE
  7. 7. 77 UI CONTROLLERS SERVICES APP Services
  8. 8. 88 ProductsController ProductsService OrdersServiceOrdersController •GetProducts •ChangeProductFieldValue •GetOrder •ChangeOrderDestination Store application
  9. 9. 99 Final state - NopCommerce
  10. 10. 1010
  11. 11. 1111 Disadvantages of this approach •Enormous controllers / services / helpers •Classes are not following SRP •Refactoring is really difficult •Complexity in writing unit tests
  12. 12. 1212 1 COMMAND AND QUERIES
  13. 13. 1313 JIMMY BOGARD CQRS IS A SIMPLE PATTERN Two objects for command/queries where once there was one https://lostechies.com/jimmybogard/2015/05/05/cqrs-with-mediatr-and-automapper/
  14. 14. 1414 WRITE SERVICES READ SERVICES UI CONTROLLERS APP Read / write services
  15. 15. 1515 UI CONTROLLERS APP Command / query handlers Command Handler Command Handler Command Handler Command Handler Query Handler Query Handler Query Handler Query Handler
  16. 16. 1616 ProductsController GetProducts QueryHandler ChangeProduct FieldValue CommandHandler Mediator GetProducts Query ChangeProduct FieldValue Command Splitting to objects
  17. 17. 1717 MediatR Simple, umambitious mediator • Simple mediator implementation in .NET • In-process messaging with no dependencies • Request/response, commands, queries, notifications, events https://github.com/jbogard/MediatR
  18. 18. 1818 public class ProductsController : ApiController { private readonly IMediator mediator; public ProductsController(IMediator mediator) { this.mediator = mediator; } [HttpGet] public IEnumerable<Product> GetProducts(GetProductsQuery query) { return this.mediator.Send(query); } [HttpPut] public void ChangeProductFieldValue(ChangeProductFieldValueCommand command) { this.mediator.Send(command); } } Splitting to objects
  19. 19. 1919 public class GetProductsQueryHandler: IRequestHandler<GetProductsQuery, IEnumerable<Product>> { private readonly IProductDatabase _database; // ctx public IEnumerable<Product> Handle(GetProductsQuery query) { var products = this._database .Products .Include(p => p.Category) .Include(p => p.FieldValues) .Include(p => p.FieldValues.Select(fv => fv.Field)); // filter products by command values return products.OrderBy(p => p.CreationDate) .Skip((query.Page - 1) * query.Take).Take(query.Take) .ToList(); } } Query handler
  20. 20. 2020 public class ChangeProductFieldValueCommandHandler :IRequestHandler<ChangeProductFieldValueCommand> { private IProductDatabase database; private ICategoryFieldService categoryFieldService; private IProductFieldHelper productFieldHelper; private IFieldValidatorFactory fieldValidatorFactory; //ctx public void Handle(ChangeProductFieldValueCommand command) { this._categoryFieldService.ValidateIfFieldCanBeAssignedToProduct (command.FieldId, command.ProductId); var fieldValidator = this._fieldValidatorFactory(command.FieldId); fieldValidator.Validate(command.FieldValue); // business logic _database.SaveChanges(); } } Command handler
  21. 21. 2121 Project structure
  22. 22. 2222 •Better structure of application •Lower entry level •Single responsibility + clean code •Clearly defined target and dependencies •Simplicity of writing unit tests Profits after this step
  23. 23. 2323 •More difficult than simple controller- database connection Disadvantages of this step
  24. 24. 2424
  25. 25. 2525 UI CONTROLLERS APP CQRS in the simplest form Command Handler Command Handler Command Handler Command Handler Query Handler Query Handler Query Handler Query Handler
  26. 26. 2626 CQRS AS A STEP
  27. 27. 2727
  28. 28. 2828 2 DIFFERENT DATA ACCESS
  29. 29. 2929 CONTROLLERS APP Command Handler Command Handler Query Handler Query Handler Command Handler Command Handler Query Handler Query Handler X Different data access
  30. 30. 3030 ProductsController GetProductsQueryHandler CategoriesController GetProductsFieldsQueryHandler AddProductCommandHandler GetCategoriesQueryHandler GetProductsWithinCategory QueryHandler AddCategoryCommandHandler Multiple objects
  31. 31. 3131 GetProductsFieldsQueryHandler AddProductCommandHandler AddCategoryCommandHandler Objects without change
  32. 32. 3232 GetProductsQueryHandler GetProductsFieldsQueryHandler AddProductsByBatch CommandHandler Request optimization
  33. 33. 3333 SQL Views Materialized AutoMapper ProjectTo Dapper MicroORM EF No tracking OrmLite MicroORM SQL Queries 6 4 5 3 1 2 Plenty of options
  34. 34. 3434 Profits of using CQRS Different data access •Ease of experiment •Focus on bottlenecks •No impact on other parts of the system
  35. 35. 3535
  36. 36. 3636 3 SIMPLE READ MODEL
  37. 37. 3737 CONTROLLERS APP Command Handler Command Handler Query Handler Query Handler Query Handler Query Handler Simple read model
  38. 38. 3838 PlaceOrder http://udidahan.com/2009/06/14/domain-events-salvation/ OrderPlace d SendEmai l DDD - Domain events Core Logic Event Side Effect
  39. 39. 3939 Command Handler https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/microservice-ddd-cqrs-patterns/domain-events-design- implementation Mediator Event Event Handler Domain events in CQRS
  40. 40. 4040 AddProduct CommandHandler ChangeProductField CommandHandler MediatorMediator ProductAdded ProductFieldChanged Publish store events
  41. 41. 4141 Product ReadModel Handler https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/microservice-ddd-cqrs-patterns/domain-events-design- implementation#single-transaction-across-aggregates-versus-eventual-consistency-across-aggregates ProductAdded ProductFieldChanged Product Read Model Create read model
  42. 42. 4242 https://github.com/jbogard/MediatR/wiki/Behaviors Command Handler Mediator Event Event Handler Event Handler Event Handler Transaction Behavior Transaction per command
  43. 43. 4343 •Ease of creating read model •Domain events straightly connected to command handlers •No data loss Profits of using CQRS Simple read model
  44. 44. 4444
  45. 45. 4545 4 ASYNCHRONOUS READ MODEL
  46. 46. 4646 CONTROLLERS APP Command Handler Command Handler Query Handler Query Handler Query Handler Query Handler Asynchronous read model
  47. 47. 4747 ProductAdded ProductFieldChanged Event Bus Product ReadModel Handler Event bus
  48. 48. 4848 Event Bus Product SearchModel Handler Product CacheModel Handler Different databases
  49. 49. 4949 Event Bus Product SearchModel Handler ProductsHub SignalR http://danielwhittaker.me/2014/10/27/4-ways-handle-eventual-consistency-ui/ Notify the user
  50. 50. 5050 •Database focused on problem •Non-blockable commands •Designed for scale Profits of using CQRS Asynchronous read model
  51. 51. 5151 •Distributed system •Eventual consistency •Operational complexity Disadvantages of using CQRS Asynchronous read model
  52. 52. 5252
  53. 53. 5353
  54. 54. 5454
  55. 55. 5555 DIFFERENT DATA ACCESS SIMPLE READ MODEL COMMAND AND QUERIES ASYNCHRONOUS READ MODEL 2 3 41 CQRS in 4 steps
  56. 56. 5656http://radblog.pl/CQRS CQRS implementation + MediatR: Jimmy Bogard - CQRS with MediatR and AutoMapper - https://lostechies.com/jimmybogard/2016/10/27/cqrsmediatr-implementation-patterns/ Jimmy Bogard - CQRS/MediatR implementation patterns https://lostechies.com/jimmybogard/2015/05/05/cqrs-with-mediatr-and-automapper/ CQRS implementation: Maciek Aniserowicza - CQRS pragmatycznie - https://kupdf.com/download/maciej-aniserowicz-cqrs-pragmatycznie_597c9425dc0d60997f2bb17f_pdf Future Processing - CQRS Simple Architecture - https://www.future-processing.pl/blog/cqrs-simple-architecture/ Derek Comartin - Fat Controllers CQRS Diet - https://codeopinion.com/fat-controller-cqrs-diet-notifications Radek Maziarka - First step - Split to commands and queries http://radblog.pl/2017/08/19/cqrs-first-step-split-to-commands-and-queries/ More generic about CQRS: Greg Young - CQRS Documencts - https://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf Greg Young - CQRS and Event Sourcing - https://www.youtube.com/watch?v=JHGkaShoyNs Microsoft - CQRS Journey - https://msdn.microsoft.com/en-us/library/jj554200.aspx Udi Dahan - Clarified CQRS - http://udidahan.com/2009/12/09/clarified-cqrs/ CQRS in Node.js https://medium.com/@domagojk/patterns-for-designing-flexible-architecture-in-node-js-cqrs-es-onion-7eb10bbefe17 Herberto Graca - From CQS to CQRS - https://herbertograca.com/2017/10/19/from-cqs-to-cqrs/ Radek Maziarka - CQRS in 4 steps - http://radblog.pl/2017/09/17/cqrs-in-4-steps-lightning-talk/ CQRS in polish: Bulldog - CQRS i Event Sourcing - https://bulldogjob.pl/articles/122-cqrs-i-event-sourcing-czyli-latwa-droga-do-skalowalnosci-naszych-systemow_ it-consulting - CQRS - http://it-consulting.pl/autoinstalator/wordpress/2012/10/18/cqrs-czyli-kto-co-i-jak-zamawia-i-dostarcza/ Łukasz Szydło - P&A + DDD + CQRS = 00 - https://www.youtube.com/watch?v=yhYFL4ujYqY
  57. 57. 5757

×