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.

Status Change: Now Using Event Sourcing @pnwphp

139 views

Published on

A description of how we moved a status-heavy application to use Events. An overview of the requirements of Events Sourcing and how the classes work together.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Status Change: Now Using Event Sourcing @pnwphp

  1. 1. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 1/58
  2. 2. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 2/58 I'm a PHP developer Organizer of Triangle PHP and Director of WWCode Raleigh/Durham I work at a company that builds tools for network security threat assessment
  3. 3. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 3/58 WHAT WE'LL COVER: Processes from paper to web forms What is Event Sourcing? Introducing what this code looks like (LIGHT) Advantages and Disadvantages
  4. 4. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 4/58 © PHOTO BY TRAVEL ORIENTED
  5. 5. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 5/58 SIGN THE WAIVER I, __(state your name)__, will not blame Emily if Event Sourcing makes my head explode. I promise I will not leave a bad review. And I promise to be kind to myself as I learn new things. Emily will not be held responsible if your head explodes
  6. 6. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 6/58 FORMS A lot of our systems were built to replace paper processes They often closely map to this physical form. © PHOTO BY AIDAN MORGAN
  7. 7. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 7/58
  8. 8. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 8/58 PAPER FORMS HANDLING STATE Status labels are like a rubber stamp Status doesn't always communicate why or what happened
  9. 9. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 9/58
  10. 10. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 10/58 WHY ARE THEY IN THE CURRENT STATE?
  11. 11. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 11/58 HOW WORKFLOWS BECOME COMPLEX
  12. 12. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 12/58 PAPER FORMS HANDLING STATE Piles indicate status of the form
  13. 13. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 13/58 A SIMPLE STATUS DROP-DOWN RECEIVED
  14. 14. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 14/58 A "SIMPLE" STATUS DROP-DOWN RECEIVED CANCELLED COURSE CANCELLED COURSE NOT APPROVED CPC DENIED CPC NOT APPROVED CPC PENDING TRANSCRIPT CPC PROCESSING DENIED DROPPED AFTER CENSUS DROPPED BEFORE CLASSES BEGUN DROPPED BETWEEN BEGINNING OF CLASS AND CENSUS DATE DROPS/WITHDRAWALS AT SITES ECE ON CAMPUS STUDENTS ENROLLMENT CANCELLED EOL APPROVED EOL MISC NEW STUDENT REGISTRATION PENDING ON CAMPUS REQUEST ON CAMPUS STUDENT NOT APPROVED PENDING CASHIER HOLD PENDING EOL APPROVAL PENDING INSTRUCTOR APPROVAL PENDING INTERNATIONAL STUDENT PENDING NDS OPEN ENROLLMENT PENDING OIS VISA STUDENT PENDING PERMANENT RESIDENT PENDING TERM ADVISEMENT HOLD PENDING TRANSCRIPT PENDING TUITION PREPAYMENT PREAPPROVED RETURNING PROCESSING NDS PROCESSING SITE PROCESSING Z PROJECT MESSAGE - MAE 586 PROJECT MESSAGE - NE 693 REGISTERED
  15. 15. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 15/58 REGISTERED REGISTERED ASHEVILLE REGISTERED HAVELOCK REGISTERED WILMINGTON SITE APPROVAL: ASHEVILLE SITE APPROVAL: HAVELOCK SITE APPROVAL: WILMINGTON SITE NOT APPROVED SWAPPED OUT TRANSCRIPT APPROVED WITHDRAWN
  16. 16. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 16/58 SOMETHING HAPPENED
  17. 17. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 17/58 SOMETHING HAPPENED Status is a reflection of something that happened There is ONE of each status + reasons/details Events can record what happened
  18. 18. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 18/58 THE REQUEST DOESN'T GET STUCK
  19. 19. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 19/58 ENTER EVENT SOURCING
  20. 20. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 20/58 DEFINITION EVENT SOURCING The fundamental idea of Event Sourcing is that of ensuring every change to the state of an application is captured in an event object, and that these event objects are themselves stored in the sequence they were applied for the same lifetime as the application state itself. Martin Fowler
  21. 21. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 21/58 WHAT'S IMPORTANT ABOUT EVENTS Events Details of the Event (attributes) Order/Sequence
  22. 22. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 22/58 RULES FOR EVENTS Events are usually named as past-tense verbs RARELY changed Never deleted Have attributes that are values never an aggregate root never a model/collection/object
  23. 23. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 23/58 THE OBJECT COULD CHANGE
  24. 24. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 24/58 IF WE STORED IT IN AN EVENT...
  25. 25. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 25/58 EVENTS ARE NOT BIONIC
  26. 26. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 26/58 THE FACT THAT AN EVENT HAPPENED DOESN'T EVER CHANGE EVEN THOUGH THE BEHAVIOR AROUND IT MAY HAVE
  27. 27. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 27/58 WHY EVENTS? state transistions are important We need an audit log and proof of state This history is more important than the current state Able to replay these events to rebuild state
  28. 28. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 28/58
  29. 29. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 29/58
  30. 30. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 30/58
  31. 31. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 31/58 Events don't change The part of the code that will change is most likely the result that follows that event. The structure of the resulting data is more likely to change than the behavior
  32. 32. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 32/58 THE CODE There are many classes involved: Events Domain Message Classes with Listeners Projections Read Models Commands & Handlers (CQRS)
  33. 33. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 33/58
  34. 34. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 34/58
  35. 35. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 35/58 <?php namespace AppEnrollmentDomainEvents; use AppEnrollmentDomainCourseOfferingId; use AppEnrollmentDomainStudentId; use AppSupportDomainUuid; use AppSupportEventHandlingEvent; class EnrollmentRequestRejected implements Event { /** * @var Uuid */ public $enrollmentRequestId; /** * @var StudentId */ public $studentId; /**
  36. 36. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 36/58
  37. 37. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 37/58 <?php namespace AppSupportDomain; use AppSupportEventHandlingEvent; use DateTime; class DomainMessage { /** * @var string */ private $streamId; /** * @var int */ private $version; /** * @var Event */
  38. 38. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 38/58 EVENT STORE A domain specific database A functional database based on a publish-subscribe messages pattern
  39. 39. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 39/58 EVENTS TABLE - NO WRAPPER
  40. 40. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 40/58 EVENTS TABLE - NO WRAPPER
  41. 41. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 41/58 O:92:"ITECSScholarshipsSelectionDomainScholarshipAwardWasAssignedToCandidateByCommitteeMember":9:{ s:6:"amount" ;O:39: "ITECSScholarshipsCommonValuesAmount":1:{ s:46:"ITECSScholarshipsCommonValuesAmountmoney" ; O:11: "MoneyMoney":2:{ s:19:"MoneyMoneyamount" ;i:285000 ;s:21:"MoneyMoneycurrency" ; O:14: "MoneyCurrency":1:{ s:20:"MoneyCurrencyname" ;s:3:"USD" ; } } } s:11:"applicantId" ; s:9:"222222235" ; s:13:"scholarshipId" ; O:61: "ITECSScholarshipsSelectionDomainScholarshipScholarshipId":1:{ s:76:"ITECSScholarshipsSelectionDomainScholarshipScholarshipIdscholarshipId" ; i:360 ; } s:17:"selectionCriteria" ;O:59: "ITECSScholarshipsSelectionDomainScholarshipCriteriaSet":1:{ s:69:"ITECSScholarshipsSelectionDomainScholarshipCriteriaSetcriteria" ;a:1:{ i:0 ;O:93: "ITECSScholarshipsSelectionDomainScholarshipSelectionCriteriaMemberOf s:106:"ITECSScholarshipsSelectionDomainScholarshipSelectionCriteriaMemberOfDepartmentCriteriondepa i:0 ;O:43: "ITECSScholarshipsCommonValuesDepartment":2:{ s:50:"ITECSScholarshipsSupportTypesCodedValuelabel" ;s:17:"Civil Engineer }
  42. 42. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 42/58 EVENTS TABLE - WITH DOMAIN MESSAGE
  43. 43. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 43/58 EVENTS TABLE - WITH DOMAIN MESSAGE
  44. 44. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 44/58 { "namespace":"AppStudentInformationEntitiesStudent", "identity":"ophelia.zieme", "data":{ "id":"ophelia.zieme", "ferpa":"0", "personal":{ "first_name":"Evan", "middle_name":"Jalon", "last_name":"Armstrong", "dob":"2007-06-16", "gender":"M" }, "contact":{ "student_id":"000811740", "username":"ophelia.zieme", "email":"ophelia.zieme@ncsu.edu", "phone":"935-516-1228" }, "address":{ "physical":{ "street1":"707 Nasir Pass", "street2":"Jett Loop", "street3":null,
  45. 45. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 45/58 LISTENERS Have methods that handle the events they care about Ignore the rest Each handle method outlines the steps to follow after an event occurs
  46. 46. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 46/58
  47. 47. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 47/58 PROJECTOR <?php namespace AppEnrollmentReadModel; use AppEnrollmentDomainEventsEnrollmentRequestRejected; use AppEnrollmentDomainEventsStudentRequestedEnrollment; use AppSupportReadModelReplayable; use AppSupportReadModelSimpleProjector; use IlluminateDatabaseSchemaBlueprint; use IlluminateDatabaseConnection; class EnrollmentRequestProjector extends SimpleProjector implements Replayable { /** * @var Connection */ private $connection; /** * @var string table we're playing events into */
  48. 48. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 48/58
  49. 49. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 49/58 READ MODEL <?php namespace AppEnrollmentReadModel; use CarbonCarbon; use IlluminateDatabaseEloquentModel; /** * @codeCoverageIgnore */ class EnrollmentRequest extends Model { protected $table = 'proj_enrollment_requests'; public $incrementing = false; public $timestamps = false; public static function current() { return static::where('student_id', auth()->user()->name)->get(); } public static function lookupRequestsFor($username) { return static::where('student_id', $username)->get();
  50. 50. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 50/58
  51. 51. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 51/58
  52. 52. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 52/58 COMMANDS <?php namespace AppEnrollmentCommands; use AppSupportCommandHandlingCommand; use AppCommonSemesterTerm; use DateTime; use IlluminateHttpRequest; class ScheduleEnrollmentPeriod implements Command { const DATE_FORMAT = DateTime::ATOM; /** * @var DateTime */ public $open; /** * @var DateTime */ public $close;
  53. 53. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 53/58 HANDLER <?php namespace appEnrollmentCommands; use AppEnrollmentDomainEnrollmentPeriod; use AppEnrollmentIdentityProvider; use AppSupportCommandHandlingCommandHandler; use AppSupportRepositoryEventSourcingRepository; use IlluminateAuthAccessAuthorizationException; class EnrollmentPeriodHandler extends CommandHandler { /** * @var IdentityProvider */ private $auth; /** * @var EventSourcingRepository */ private $repository; public function __construct(IdentityProvider $auth, EventSourcingRepository $repository)
  54. 54. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 54/58 PROS maps closely to the process flexible to changes in process meaning of events can change without altering history scholarships; able to back up all events to roll over a new year. Didn't need to preserve full database.
  55. 55. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 55/58 CONS a lot of classes more design patterns to adjust to (complicated)
  56. 56. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 56/58
  57. 57. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 57/58 LINKS FOR FURTHER READING (+2 more) Greg Young CQRS and Event Sourcing Greg Young - long class Greg Young - A Decade of DDD, CQRS, Event Sourcing PHP Round Table - Event Sourcing Broadway - framework for CQRS and ES
  58. 58. 9/8/2017 Status Change: Now Using Event Sourcing http://localhost:8080/status_change.html#/ 58/58 THANK YOU! Emily Stamey Joind.in: @elstamey https://joind.in/talk/a0c6e @elstamey https://joind.in/talk/a0c6e

×