Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Event Sourcing 101

Avatar for disc99 disc99
December 09, 2018

Event Sourcing 101

Avatar for disc99

disc99

December 09, 2018
Tweet

More Decks by disc99

Other Decks in Technology

Transcript

  1. Πϕϯτιʔγϯάͷಛ௃ w աڈͷཤྺ Πϕϯτ Λ͢΂ͯอଘ σʔλͷߋ৽͸͠ͳ͍  w ཤྺ͔Βݱࡏঢ়ଶΛ෮ݩ w

    ৘ใ͕ফࣦ͠ͳ͍ͨΊɺޙ͔ΒϏδωεϩδοΫΛมߋ͠΍͍͢ w ཁ݅Λͦͷ··ιʔείʔυͰදݱ͠΍͍͢ w ֎෦γεςϜ΋ΠϕϯτͷίϯγϡʔϚʹͳΓɺτϥϯβΫγϣϯ΍ґଘؔ܎ ͕ܰݮ w ΠϕϯτετΞͷଞʹݕࡧʹಛԽͨͨ͠͠σʔλετΞ
  2. .7$

  3. w ॻ͖ࠐΈܥͷෳࡶੑ w େྔͷ৚݅෼ذ΍ɺෳࡶͳϏδωεϧʔϧɺԋࢉ w ৽نɺԼॻ͖ɺߋ৽ͱ͔Λಉ͡.PEFMͰѻ͏ w ϢʔεέʔεʹΑͬͯOVMM΍ɺόϦσʔγϣϯ͕ҧ͏ w ಡΈࠐΈܥͷෳࡶੑ

    w ߋ৽ͷͱ͖͸ϦϨʔγϣϯઌͷ*%͚ͩ͋Ε͹͍͍ w औಘʹ͸*%Ͱ+PJOͨ݁͠Ռ΋΄͍͠ w ୯Ұͷ.PEFMऔಘ͸ৄࡉɺෳ਺.PEFMͷ৔߹͸αϚϦʔ͚ͩ͋Ε͹͍͍
  4. w ॻ͖ࠐΈܥͷෳࡶੑ w େྔͷ৚݅෼ذ΍ɺෳࡶͳϏδωεϧʔϧɺԋࢉ w ৽نɺԼॻ͖ɺߋ৽ͱ͔Λಉ͡.PEFMͰѻ͏ w ϢʔεέʔεʹΑͬͯOVMM΍ɺόϦσʔγϣϯ͕ҧ͏ w ಡΈࠐΈܥͷෳࡶੑ

    w ߋ৽ͷͱ͖͸ϦϨʔγϣϯઌͷ*%͚ͩ͋Ε͹͍͍ w औಘʹ͸*%Ͱ+PJOͨ݁͠Ռ΋΄͍͠ w ୯Ұͷ.PEFMऔಘ͸ৄࡉɺෳ਺.PEFMͷ৔߹͸αϚϦʔ͚ͩ͋Ε͹͍͍ ॻ͖ࠐΈͱಡΈࠐΈΛ෼͚Δ
  5. $POUSPMMFS w ී௨ͷ4QSJOH$POUSPMMFS w ඇಉظॲཧͷͨΊʹ $PNQMFUBCMF'VUVSF @RestController @RequestMapping("/accounts") class BankAccountApi

    { @PostMapping CompletableFuture<String> createAccount(@RequestBody AccountOwner user) { // … } @PutMapping(path = "{accountId}/balance") CompletableFuture<String> deposit(@RequestBody Balance balance, @PathVariable String accountId) { // … } @DeleteMapping("{id}") CompletableFuture<String> delete(@PathVariable String id) { // … } @GetMapping("{id}") CompletableFuture<BankAccountDto> findById(@PathVariable String id) { // … } }
  6. $PNNBOE(BUFXBZ w "YPO͕ఏڙ w TFOE ʹΑͬͯ$PNNBOE .PEFMΛૹ৴ @RestController @RequestMapping("/accounts") class

    BankAccountApi { CommandGateway commandGateway; @PostMapping CompletableFuture<String> createAccount(@RequestBody AccountOwner user) { String id = UUID.randomUUID().toString(); return commandGateway.send(new CreateAccountCommand(id, user.getName())); } }
  7. $PNNBOE.PEFM w ৼΔ෣͍Λ࣋ͨͳ͍ී௨ ͷ#FBO w !5BSHFU"HHSFHBUF*EFOUJ pFS͸%PNBJO.PEFMͱର Ԡ class CreateAccountCommand

    { @TargetAggregateIdentifier String id; String accountCreator; } class WithdrawMoneyCommand { @TargetAggregateIdentifier String id; double amount; }
  8. %PNBJO.PEFM w !"HHSFHBUF !"HHSFHBUF*EFOUJpFSͰम০ w !$PNNBOE)BOEMFS w $PNBOOE.PEFMͷॲཧ w BQQMZ

    Ͱ&WFOUൃߦ w !&WFOU4PVSDJOH)BOEMFS w &WFOUͷॲཧ w ϏδωεϩδοΫͷू໿ w ݱ࣮ͷཁ݅Λهड़ w ޱ࠲ #BOL"DDPVOU  w ޱ࠲ʹೖۚ͢Δ %FQPTJU.POFZ$PNNBOE  w ޱ࠲ʹೖۚ͞Εͨ .POFZ%FQPTJUFE&WFOU  w υϝΠϯʹෆཁͳॲཧ͸"YPOଆͰࣗಈ࣮ߦ w σʔλ &WFOU ͷอଘ w &WFOUཤྺ͔Βݱࡏঢ়ଶͷ෮ݩ SFQMBZ @Aggregate class BankAccount { @AggregateIdentifier String id; double balance; String owner; @CommandHandler void on(DepositMoneyCommand command) { double amount = command.getAmount(); Assert.isTrue(amount > 0.0, "Deposit must be a positive number."); apply(new MoneyDepositedEvent(id, amount)); } @EventSourcingHandler void on(MoneyDepositedEvent event) { this.balance += event.getAmount(); } }
  9. &WFOU4UPSF w "YPO͕ఏڙ w BQQMZ ͞Εͨ&WFOUΛશ ͯอଘ w อଘ͞Εͨ&WFOU͸4USFBN ͱͯ͠औΓग़ͤΔ

    &WFOU 4USFBN @RestController @RequestMapping("/accounts") class BankAccountApi { EventStore eventStore; List<Object> getEvents(@PathVariable String id) { return eventStore.readEvents(id).asStream() .map(Message::getPayload) .collect(toList()); } }
  10. &WFOU-JTUFOFS w !&WFOU)BOEMFS w &WFOUΛड͚औΔ w ݕࡧ༻ͷετΞʹ൓ө w ͦͷଞͷ༻్ʹ΋ class

    BankAccountEventListener { BankAccountRepository repository; @EventHandler void on(AccountCreatedEvent event) { BankAccountEntity entity = new BankAccountEntity( event.getId(), event.getBalance(), event.getAccountCreator() ); repository.save(entity); } }
  11. 2VFSZ(BUFXBZ w "YPO͕ఏڙ w RVFSZ ʹΑͬͯ2VFSZ .PEFMΛૹ৴ @RestController @RequestMapping("/accounts") class

    BankAccountApi { QueryGateway queryGateway; @GetMapping("{id}") CompletableFuture<BankAccountDto> findById(@PathVariable String id) { BankAccountQuery query = new BankAccountQuery(id); return queryGateway.query(query, BankAccountDto.class); } }
  12. 2VFSZ4FSWJDF w υϝΠϯΛ͋·Γҙࣝ͠ͳ ͍खଓ͖తॲཧ w !2VFSZ)BOEMFS w 2VFSZ.PEFMΛऔಘ w ී௨ͷݕࡧ

    @Service public class BankAccountQueryService { BankAccountRepository bankAccountRepository; @QueryHandler public BankAccountDto findById(BankAccountQuery query) { return bankAccountRepository.findById(query.getId()) .map(BankAccountDto::new).orElseThrow(RuntimeException::new); } }