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

[TDC Floripa] Event Driven Architecture

[TDC Floripa] Event Driven Architecture

Camila Campos

April 23, 2019
Tweet

More Decks by Camila Campos

Other Decks in Programming

Transcript

  1. @camposmilaa Camila Campos Dev @ Creditas Organizadora Rails Girls SP

    Organizadora Women Dev Summit @camposmilaa no Twitter
  2. @camposmilaa Plataforma online Empréstimo com garantia Juros baixos pra você

    <3 creditas.com.br vagas.creditas.com.br @CreditasBR
  3. @camposmilaa Junção de comunidades Incentivar mulheres em tech Palestras &

    Oficinas & Painéis womendevsummit.com fb.com/womendevsummit @WomenDevSummit
  4. @camposmilaa "OOP to me means only messaging, local retention and

    protection and hiding of state-process, and extreme late-binding of all things." Alan Kay
  5. @camposmilaa "The big idea is messaging [...] The key in

    making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be" Alan Kay
  6. @camposmilaa PRODUTO - nome - preço PEDIDO - data da

    compra CLIENTE - cpf - nome - data de nascimento
  7. @camposmilaa Vida real (correio) Mensageria RPC Conteúdo informação informação ou

    referências referências Sincronicidade assíncrona assíncrona síncrona Conteúdo errado ¯\_(ツ)_/¯ ¯\_(ツ)_/¯ Sem receptor ¯\_(ツ)_/¯ ¯\_(ツ)_/¯
  8. @camposmilaa Solicitei um empréstimo Preenchi o cadastro Enviei documentos Meu

    crédito foi aprovado O empréstimo foi concedido 1. 2. 3. 4. 5.
  9. @camposmilaa Event Sourcing Evento Cliente Cadastrado {nome: Joaquina, cpf: 12345678900}

    Solicitação criada {valor: 50.000, motivo: Reforma} Documento adicionado {tipo: Identidate}
  10. @camposmilaa Cliente cadastrado Solicitação criada Documento adicionado Documento removido Valor

    solicitado alterado Valor alterado Doc adicionado Doc removido Doc adicionado Solicitação criada Cliente cadastrado Documento adicionado
  11. @camposmilaa CQRS Solicitar crédito Command Model Query Model Ver crédito

    Escrita Leitura Banco de escrita Banco de leitura
  12. @camposmilaa CQRS + Event Sourcing Event Sourcing (escrita) Banco de

    leitura evento 1, id: 2 evento 2, id: 1 evento 1, id: 1 id: 1, estado 2 id: 2, estado 1
  13. @camposmilaa Valor alterado Doc adicionado Doc removido Doc adicionado Solicitação

    criada Cliente cadastrado Cliente Solicitações Documentos
  14. @camposmilaa Valor alterado Doc adicionado Doc removido Doc adicionado Solicitação

    criada Cliente cadastrado Cliente Solicitações Documentos Query
  15. @camposmilaa src/vehicle-data/get-vehicle-data.js | 2 +- test/infra/get-molicar-versions.test.js | 10 +++++----- test/use-case/fetch-vehicle-data.test.js

    | 2 +- test/vehicle-data/get-vehicle-data.test.js | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-)
  16. @camposmilaa Tópico 0 1 2 3 4 5 6 0

    1 2 3 4 5 6 7 8 9 10 11 12 0 1 2 3 4 5 6 7 8 9 Partição 1 Partição 2 Partição 3
  17. @camposmilaa Não é complicada 1. 2. 3. 4. 5. 6.

    Event Driven Architecture 1. 2. 3. 4. 5. 6.
  18. @camposmilaa Não é complicada Reflete a realidade 1. 2. 3.

    4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  19. @camposmilaa Não é complicada Reflete a realidade Auditoria "de graça"

    1. 2. 3. 4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  20. @camposmilaa Não é complicada Reflete a realidade Auditoria "de graça"

    Serviços autônomos 1. 2. 3. 4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  21. @camposmilaa Não é complicada Reflete a realidade Auditoria "de graça"

    Serviços autônomos Escalável 1. 2. 3. 4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  22. @camposmilaa Não é complicada Reflete a realidade Auditoria "de graça"

    Serviços autônomos Escalável Análises mais complexas 1. 2. 3. 4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  23. @camposmilaa Assincronia Não é complicada Reflete a realidade Auditoria "de

    graça" Serviços autônomos Escalável Análises mais complexas 1. 2. 3. 4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  24. @camposmilaa Assincronia Consistência Eventual Não é complicada Reflete a realidade

    Auditoria "de graça" Serviços autônomos Escalável Análises mais complexas 1. 2. 3. 4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  25. @camposmilaa Assincronia Consistência Eventual Correções por eventos Não é complicada

    Reflete a realidade Auditoria "de graça" Serviços autônomos Escalável Análises mais complexas 1. 2. 3. 4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  26. @camposmilaa Assincronia Consistência Eventual Correções por eventos Demanda projeções Não

    é complicada Reflete a realidade Auditoria "de graça" Serviços autônomos Escalável Análises mais complexas 1. 2. 3. 4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  27. @camposmilaa Assincronia Consistência Eventual Correções por eventos Demanda projeções Replay

    tenso Não é complicada Reflete a realidade Auditoria "de graça" Serviços autônomos Escalável Análises mais complexas 1. 2. 3. 4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  28. @camposmilaa Assincronia Consistência Eventual Correções por eventos Demanda projeções Replay

    tenso Overengineering Não é complicada Reflete a realidade Auditoria "de graça" Serviços autônomos Escalável Análises mais complexas 1. 2. 3. 4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  29. @camposmilaa class CommandConsumer < ::Karafka::BaseConsumer def consume command_name = params.dig('metadata',

    'name') use_case = use_case_from(command_name) use_case.execute(command_from(params)) end def use_case_from(command_name) # ... def command_from(message) # ... end
  30. @camposmilaa class CommandConsumer < ::Karafka::BaseConsumer def consume command_name = params.dig('metadata',

    'name') use_case = use_case_from(command_name) use_case.execute(command_from(params)) end def use_case_from(command_name) # ... def command_from(message) # ... end
  31. @camposmilaa class CommandConsumer < ::Karafka::BaseConsumer def consume command_name = params.dig('metadata',

    'name') use_case = use_case_from(command_name) use_case.execute(command_from(params)) end def use_case_from(command_name) # ... def command_from(message) # ... end
  32. @camposmilaa class CriarSolicitacaoCommand < ::Dry::Struct attribute :pessoa, Types::Pessoa attribute :garantia,

    Types::Garantia end class CriarSolicitacaoUseCase def execute(command) solicitacao = Solicitacao.new(command.to_h) repository.save(solicitacao) end end
  33. @camposmilaa class CriarSolicitacaoCommand < ::Dry::Struct attribute :pessoa, Types::Pessoa attribute :garantia,

    Types::Garantia end class CriarSolicitacaoUseCase def execute(command) solicitacao = Solicitacao.new(command.to_h) repository.save(solicitacao) end end
  34. @camposmilaa def solicitacao_criada_handler(evento) @pessoa = Pessoa.new(evento.pessoa) garantias << criar_garantia(evento.garantia) end

    def apply_changes(event) pending_events << event event_handlers[event.class].call(event) end end
  35. @camposmilaa def solicitacao_criada_handler(evento) @pessoa = Pessoa.new(evento.pessoa) garantias << criar_garantia(evento.garantia) end

    def apply_changes(event) pending_events << event event_handlers[event.class].call(event) end end
  36. @camposmilaa class SolicitacaoRepository def save(solicitacao) eventos = solicitacao.pending_events # limpar

    lista de eventos pendentes eventos.each do |evento| events_table.insert( event: JSON.dump(evento.to_h)) end end end
  37. @camposmilaa class SolicitacaoRepository def save(solicitacao) eventos = solicitacao.pending_events # limpar

    lista de eventos pendentes eventos.each do |evento| events_table.insert( event: JSON.dump(evento.to_h)) end end end
  38. @camposmilaa class SolicitacaoRepository def save(solicitacao) eventos = solicitacao.pending_events # limpar

    lista de eventos pendentes eventos.each do |evento| events_table.insert( event: JSON.dump(evento.to_h)) end end end
  39. @camposmilaa class SolicitacaoRepository def save(solicitacao) eventos = solicitacao.pending_events # limpar

    lista de eventos pendentes eventos.each do |evento| events_table.insert( event: JSON.dump(evento.to_h)) end end end
  40. @camposmilaa class SolicitacaoRepository def save(solicitacao) eventos = solicitacao.pending_events # limpar

    lista de eventos pendentes eventos.each do |evento| events_table.insert( event: JSON.dump(evento.to_h)) end EstadoAtual.new.save(caixa) end end