Salve, Deus, beleza? Continuamos essa saga aqui no Domain Dream Design, então a gente está chegando ao capítulo final aqui do nosso módulo de DDD. E agora que a gente já passou por toda essa trajetória, toda essa saga que eu venho falando desde lá do começo, algumas dúvidas com certeza surgiram e eu queria falar sobre algumas delas aqui e algumas das que são mais recorrentes. A gente vai começar aqui pelo assunto dos agregados. Nós falamos aqui durante esse módulo da regra dos agregados. Na verdade, até eu não me referi a esse termo, mas lá no livro do Valgvernon, ele fala sobre regra dos agregados, as regras que você deve seguir. Então, todo agregado deve ser uma transação atômica, ou seja, não é que eu estou salvando ali aquele agregado inteiro que pode ter subentidades ou objetos de valores. Ao terminar, tem que salvar tudo. Se eu salvei só um pedaço, tem que descartar. Ou eu salvo tudo, ou não salvo nada. tem que descartar. Ou eu salvo tudo ou não salvo nada. O agregado protege as invariantes de consistência. Então, toda transação, todo comando que acontece ali passa por esse agregado. Esse agregado que garante que todas as regras de negócio estão satisfeitas, estão consistentes. Então, a gente não acessa nenhuma subentidade, nada ali, sem que se passe por agregado. Ele é o guardião da nossa consistência. Um agregado só pode se referenciar aos outros por identidade, que é o caso que a gente fez aqui no curso. Quando eu tenho lá a relação do evento com o parceiro, parceiro e evento são dois agregados, então lá dentro de evento eu só coloco a identidade do parceiro. E nesse caso, os dois agregados têm um acoplamento fraco, porque quando acontece alguma mudança no parceiro, não vai mudar a identidade dele, então não acontece mudança nos eventos. E aqui que vem um ponto que divide muito a comunidade de tecnologia no que tange ao DDD. Essa aqui é a regra mais espinhosa. Somente um agregado deve ser processado por transação. O que isso significa? Pegando o orderService que nós fizemos aqui, no método create, não significa que a consulta, significa persistência. Quantos agregados nós estamos utilizando aqui para poder fazer a persistência? Esse aqui vai ser um deles, o Spot Reservation. Nós vamos também persistir o Order. E o evento acaba sendo persistido, ou seja, nós temos três agregados. Essa é a regra de negócio. Então, a regra é que somente um agregado deve ser processado por transação. Qual que é a ideia aqui do Vernon? Ele está querendo dizer o seguinte, olha, você usa um agregado aqui para fazer a sua regra de negócio, salva. aqui para fazer a sua regra de negócio, salva. Se você precisa, se esse processo de negócio vai afetar outros agregados, faça isso fora daquele processo que você fez. Faça isso com determinado atraso, utilizando uma fila de mensagens, colocando isso em background. E essa visão é muito importante porque às vezes a gente imagina que tudo que tem que acontecer num processo de negócio tem que acontecer de forma completa. Nada pode ficar inconsistente ali durante um tempo. E principalmente em sistemas de grande escala, isso não é possível. Você tem um processo de negócio, ele vai acontecer um pedaço dele, depois de passar alguns segundos vai acontecer o próximo passo, vai acontecer o próximo passo, até que eu tenha a finalização disso. Se alguma dessas etapas ali que envolvem os agregados acontecer um erro, a gente acaba tendo compensações e coisas do tipo. Aí vai entrar assuntos como saga, coreografia, que eu não vou abordar aqui nesse módulo. Mas a questão é que às vezes a gente imagina que tem que fazer um processo de negócio, tem que processá-lo em todos os agregados na mesma transação. Isso torna o processo de negócio muito mais difícil. E a gente tem que entender que se precisasse de alguns segundos, difícil. E a gente tem que entender que se precisasse de alguns segundos, até os próprios domain experts vão entender isso. Não, tipo assim, se demorar alguns segundos para que seja processado ali a alteração no agregado, isso não tem problema. Às vezes até alguns segundos generosos, como o Valguverno fala no próprio livro. Então a gente tem que saber que o tempo real, às vezes, não é necessariamente tudo de uma vez só. É um intervalo pequeno de tempo. Então, a gente precisa entender o quão eu posso... Quanto mais eu puder adiar um processamento de agregado aqui para o meu processo de negócio, melhor. Quanto menos agregados estiverem envolvidos aqui no meu processo de negócio, é mais fácil eu poder lidar com a consistência de dados, com as próprias regras de negócio, com o processo transacional. E eu vou delegando a outros agentes depois. A gente viu aqui que é possível fazer um transaction outbox. Então, aqueles listeners que nós criamos aqui, viu aqui que é possível fazer um transaction outbox, então aqueles listeners que nós criamos aqui, apesar da gente imaginar que eles vão ser executados... Deixa eu até deixar essa linha aqui de cima. Eles vão ser executados sempre ali no branch of work, mas não. Eles podem ser executados também de forma assíncrona. Eu posso notificar o meu contexto local utilizando uma fila local, a própria mensageria, o próprio ReptMQ da vida, para poder fazer esse processo. Eu vou dar um exemplo para vocês sobre isso. Como a gente poderia reduzir isso. Mas aí a gente tem que analisar o contexto do negócio. Eu fiz a reserva. A reserva é algo inegociável aqui, se a gente for que analisar o contexto do negócio. Eu fiz a reserva. A reserva é algo inegociável aqui, se a gente for olhar no final das contas. Eu tenho que fazer a reserva aqui para poder já garantir o lugar, senão o usuário perde. E fazer o pagamento e criar essa ordem. E criar essa ordem. Mas marcar lá no agregado de evento que aquele spot está reservado isso aqui poderia ir justamente primeiramente para um listener para tirar daqui poder criar um listener que vai ouvir aqui quando uma order é paga pagou pega aqui e manda. Ele vai ter acesso ali ao ID da sessão, qual o spot específico. Pronto. Consegui fazer isso, não isso. Mas e se eu quisesse fazer isso em background alguns segundos depois? Também não teria problema. Então, isso aqui poderia ser delegado. Mas e como é que fica esse caso, então, da nossa regra de negócio? Ela está usando três agregados aqui, isso está errado, está certo? O Vernon cita, depois, lá no capítulo da regra dos agregados, ele coloca razões para quebrar as regras dos agregados. Às vezes, você pode ter alguma conveniência na interface de usuário ali que ele está trabalhando, criando vários agregados, então você recebe isso na sua aplicação, você precisa, às vezes, lidar com vários agregados do mesmo tipo. Vamos supor que seja uma lista de alguma coisa. Aí, cada item da lista é um agregado. Você precisa salvá-los ao mesmo tempo. E não é por causa ali da interface. Você tem essa restrição que você tem que manter ela na sua application service. Às vezes, a falta de mecanismos técnicos. E eu até colocaria aqui a falta de mecanismos técnicos. E eu até colocaria aqui a falta de mecanismos técnicos ou restrições de negócio também. Aqui que vai caber a nossa quebra. Por que esse order service aqui está correto? Porque dado a nossa situação que a gente precisa vender, pagar e já saber se está tudo certo, é cartão de crédito e acabou, então eu não posso delegar isso a uma consistência futura, uma consistência eventual. Eu não posso deixar para depois para ver se está tudo certo, eu preciso ver ali na hora. Então ou a gente encontra um outro modelo de agregado que a gente consegue fazer tudo, mas aí tem sempre o problema de garantir que só uma pessoa reserve o ingresso, ou a gente tem que fazer, a gente tem que manusear todos esses agregados. O único que daria para poder adiar, ou pelo menos para poder colocar ali num listener e tiraria mais responsabilidade daqui, é essa parte. Poderia ser processado, uma consistência futura ou num listener. Mas também às vezes acontece que você está num projeto que por vários motivos você não consegue trabalhar com essa consistência futura, você não tem essa disponibilidade de usar mensageria. Então, você usa ali os listeners e os services no mesmo processamento. Às vezes acontece também de você ter uma aplicação legada, aqui são mais voltados para aplicações legadas, pelo contexto da aplicação, você tem transações globais que acontecem, então você quer processar esses agregados ali porque não vai valer a pena adiar a aplicação. Já tem uma forma de trabalhar, você precisa respeitar aquela situação. Também tem o desempenho das consultas, isso aqui remete mais à questão de referência dos agregados, que aqui ele está falando o seguinte. de referência dos agregados, aqui ele está falando o seguinte. Um agregado só se referencia ao outro por ID, mas às vezes pelo desempenho ali ao lidar com a consulta desses agregados, você sempre vai ter que consultar um agregado e consultar o outro para poder dar uma resposta satisfatória no seu Application Service. Então, se você manter aqui a referência, não só a identidade, mas a referência ali ao outro agregado, vai ter um desempenho melhor. Então, a gente tem essas razões para quebrar, mas são razões que nós precisamos justificar muito bem. A gente precisa saber o que está fazendo. A questão é, o livro DDD não te dá respostas a todos os seus problemas, a todas as suas perguntas. E não existe uma forma, não existe uma religião a ser seguida. Sempre você tem que respeitar principalmente as questões técnicas e as restrições de negócio. Então não significa que se você estiver quebrando uma regra, você não esteja usando o DDD, você está quebrando essas regras justamente para satisfazer questões de negócio, e a gente já viu aqui no MBA que questões de negócio é que são sagradas, essas precisam ser devidamente respeitadas. Mas a questão é que sempre tente manter os seus agregados, um agregado por processo, por transação, e sempre tentando adiar o impacto em cima dos outros agregados. Você pode ter os seus listeners ali fazendo as execuções, como a gente tem aqui o event sourcing, que tem que acontecer ali no processo, mas a gente até poderia colocar ele também ali na fila lá do Bull.js para poder ser salvo depois. Porque uma vez que eu salvei ele no Redis ou no meu banco de dados, ele pode ser armazenado logo em seguida também. Mas normalmente a gente coloca na mesma transação, porque a gente já garante, é muito leve, né? Estou adicionando apenas um insert e mais uma tabela ali, é muito simples. Então, pessoal, vamos continuar nossa saga, nós vamos responder ainda outras perguntas aqui durante esse módulo. É isso aí, e até a próxima.