polêmica por causa que a gente é muito acostumado a trabalhar com a mentalidade de crude. O assunto hoje é justamente esse carinha que não tem pra onde a gente correr, porque de forma geral, grande parte dos sistemas que a gente desenvolve, provavelmente todos os sistemas aqui que vocês estão desenvolvendo, vai envolver algum crude de uma maneira ou de outra. Independente do que você faça, você vai acabar trabalhando ali com algum storage e quase 100% vai ser um banco de dados, certo? E a gente vai ver aqui nessa aula como que essa mentalidade do CRUD, ela conta tanto a modelagem do software, quanto o desenvolvimento. E, de certa forma, isso é natural, porque dado já há décadas que as coisas funcionam dessa forma, a gente acaba aprendendo a pensar o software dessa forma, mas quando você pensa no CRUD como o centro das atenções do seu software, você vai criar softwares que não vão atender aos requisitos de negócio, vão ser difíceis de manter e vão custar caro ao longo do tempo, tá? A gente vai, daqui a pouco, ver um pouco de código aqui pra entender algumas coisas. Eu vou falar sobre orientação a objetos, mas esse assunto serve também pra outros paradigmas de programação, não necessariamente pra orientação a objetos. E uma das coisas que a mentalidade de crude faz é que a gente tá usando orientação a objeto, mas não é programação orientada a objeto. A orientação a objeto, mas não é programação orientada a objeto. A princípio, isso não tem problema nenhum de você trabalhar dessa forma. Você vai usar ali um JavaScript, um Python, um Java para poder desenvolver a sua aplicação, você não usa de fato a essência da orientação a objeto. Mas a questão é que determinados projetos, se você não utiliza essa essência, você vai estar perdendo, como a gente já falou, tá? E o que a gente vai ver aqui na aula hoje é como a gente sai dessa mentalidade, a gente vai ver um exemplo muito ruim de como que a gente poderia modelar um sistema e depois de uma modelagem mais adequada, né? Não quero dar spoilers, a gente vai falando sobre isso ao longo aqui da aula. Beleza, então eu vou compartilhar aqui minha tela. Eu tenho aqui um pequeno projeto, inclusive deixa eu deixar o chat aberto aqui para ver também. Qualquer coisa que vocês quiserem perguntar e etc quiser também abrir o microfone pra falar qualquer coisa, estejam à vontade então vamos pegar aqui uma ideia que a gente vai trabalhar com um projeto de gerenciamento de projetos então imagina lá que eu posso criar um projeto e acompanhar todas as tarefas que tem que ser desenvolvidas naquele projeto ali. Aquele projeto vai ter uma data de início, uma data de fim, e cada tarefa que eu vou associando com esse projeto também tem uma data de início e uma data de fim. Então a gente poderia criar aí um board, fazer alguma coisa, que eu conseguisse ali ver os meus projetos e ver as tarefas que terminaram, que não terminaram, coisas nesse sentido. Então, a gente vai ter aqui esses casos de uso, eu acredito que tá a tela boa, né, que eu dei dois uns aqui, acho que tá bom pra todo mundo ver. Tá perfeito. Então, pra um projeto, quando for criar um projeto, eu tenho que passar ali o nome desse projeto, a descrição, a data de início e a data de previsão. Essas duas datas aqui não vão ser obrigatórias. Se quiser passar, eu passo. Se for passar da data de início, então esse projeto vai ser marcado, a gente vai ter um status, vai marcar ele como iniciado. Tá? Mas se eu não passar essa data de início, ele vai estar com status pendente. Mas aí esse projeto, ele transita entre três status. Se ele não tá iniciado, eu posso iniciar esse projeto com uma data de início, eu posso finalizar ele com a data final ali, que significa que ele terminou, ou às vezes tem um cancelamento, eu posso cancelar com uma data de cancelamento. Certo? Cada task que eu for agregar nesse projeto, então eu vou adicionar ali uma nova tarefa, eu vou passar o ID, qual o identificador desse projeto, o nome e a descrição, a data de início e a data de previsão, é quando essa task estará, quando ela ficará pronta, né. Se for passada a data de início, também essa task deve ser marcada como iniciada, então a gente também vai transitar no status dessas tasks. task deve ser marcado como iniciado. Então, a gente também vai transitar no status dessas tasks. Então, ela vai poder estar pendente, ela foi iniciada, ela foi finalizada ou ela foi cancelada. Mas a gente vai ter outras restrições aqui, vamos supor que a gente conversou ali com um especialista que vai usar esse software, ele falou, olha, se o projeto aqui tiver cancelado ou tiver finalizado, eu não posso mais reverter ele para o status lá que ele está ativo. Cancelou, cancelou, completou, finalizou, está finalizado. A mesma coisa serve para task, beleza? Então, dado isso aqui, a gente vai criar uma API REST, né? Ah, tem que ser uma aplicação web e tal, então vamos lá para os endpoints. Qual que é a primeira coisa que a gente vai fazer? Tá, eu vou criar um projeto, vou fazer um barra post, ou melhor, um post barra projetos, passando o nome, a descrição, a data que ele vai iniciar, que não é obrigatória, e o forward casted at, que é quando esse projeto estaria pronto. Recebo ali a resposta do ID do projeto, o nome e a descrição, as duas datas também. Beleza, a princípio aqui, se a gente não está pensando ainda em banco de dados, se a gente não está pensando em como a gente vai fazer qualquer tipo de modelagem na área de negócios, mas a princípio está ok. Eu vou criar um projeto, faço um post barra projetos, ou melhor, barra project, inclusive, depois eu vou mostrar o código aqui, eu coloquei o que eu estava pensando em traduzir. Então, o post, todo mundo já sabe que você está querendo criar algo, né? Não tem nenhum problema. Agora, é e pra fazer as operações aqui de transitar o estado desse projeto. Ele pode não ter sido iniciado, eu vou iniciar, eu vou finalizar ele em algum momento, ou cancelá-lo. Então, qual que é o primeiro verbo que viria a cabeça da gente? Patch, né? Poxa, então eu tô pensando assim, eu tenho que... esse trânsito de estados aqui vai fazer com que eu tenha que atualizar o meu projeto. Então eu vou fazer um patch. Se quiser também usar um put, não tem nenhum crime nisso aqui também, mas a ideia é só que eu teria dois candidatos a fazer essa regra de negócio, né? Vamos dar uma olhadinha aqui teria dois candidatos a fazer essa regra de negócio. Vamos dar uma olhadinha aqui como que ficaria, o meu código aqui é JavaScript, acho que não tem ninguém que vai ter uma grande dificuldade de fazer o entendimento. Se eu quiser criar o meu projeto, eu tenho ali uma rota aqui com o express do node barra projects, recebo os dados, chamo ali um service layer que eu tenho, passando essas informações, as datas aqui não são obrigatórias, então por isso que eu estou verificando se ela foi passada para poder converter para uma data, mas aí eu tenho aqui o projeto criado, beleza, então aqui eu tenho o meu atualizar, beleza. Então, aqui eu tenho o meu atualizar, né, que inclusive eu até coloquei patch lá, coloquei put aqui, né, mas, enfim, isso não importa muito. A princípio, quando a gente olha pra esse, essa, esse endpoint criado aqui, poxa, não, tá simples, né, porque eu recebo as três datas que me ajudam a transitar o estado, a gente vai ter um método update dentro do project service. Então eu passo elas aqui no project service que tá se virando. Então eu faço update, poxa, tá? Ok. Tá, vamos dar uma olhadinha dentro desse método update? É porque eu já estou pensando, assim, que essas transições é um atualizar. Então, isso me incentivou a criar esse atualizar na minha camada de serviços. Então, eu recebo o ID do projeto que eu quero atualizar, nome e descrição. Nenhuma dessas informações são obrigatórias, né, porque eu posso estar querendo atualizar, ah, eu quero atualizar apenas o nome ou a descrição, ou o nome e a descrição, ou fazer ali, eu quero iniciar o projeto, quero finalizar ele, eu quero cancelar, tá. Então, a primeira coisa que a gente acaba fazendo é consultar esse projeto, certo? Eu não estou aqui preocupando com qual tipo de banco de dados, né? Inclusive esse repositório que eu estou trabalhando aqui o pessoal aí talvez tenha visto já módulo de Clean Architecture do Gabriel Soar, que é o meu ali de Domain Driven Design, aqui não é o repositório lá de DDD, esse repositório aqui é apenas porque eu estou utilizando uma lib da comunidade JavaScript, que é o type urm ele lida, isso aqui é o repo lá da lib apenas pra gente poder lidar com uma entidade que eu modelei, daqui a pouco eu mostro essa entidade. Então eu consultei esse projeto, ah, foi passado o nome? Então, vou alterar o nome. Ah, foi passada a descrição? Ah, então, foi passada... Vou alterar a descrição. Foi passada a data de previsão? Então, eu alterei a data de previsão. Aí, agora, aqui, começa a nossa brincadeira com o transitar do estado desse projeto. Ah, eu passei uma data de started at. Então, a gente tem que fazer algumas verificações. Eu não coloquei aqui todas as verificações, mas eu tenho que verificar se esse projeto já não está ativo. Se ele já estiver ativo, eu não vou ativar. Então, eu lanço o erro. Tem que verificar também se ele não está completo. Eu não posso ativar um projeto que já está completo. Então, também eu vou ter um erro para isso. Se ele estiver cancelado também, eu não posso ativar. Beleza. Aí, eu vou pegar a data que foi passada, passo para a minha data ali, altero o meu status, agora está ativo. Beleza. A gente vai salvar isso aqui depois. Então, a gente vai acabar fazendo isso para o cancelado, então se eu receber essa data, a gente vai fazer também o mesmo processo, algumas verificações, para poder cancelar, ele não pode estar completado, ele não pode já estar cancelado, e a data de cancelamento não pode ser menor que a data quando ele iniciou. Então, eu tenho algumas verificações para poder fazer esse processamento de negócio. Beleza, passou por tudo isso aqui, então eu vou armazenar minha data de cancelamento, o status é cancelado, e aí se eu tiver tasks que estão ativas também, eu verifico aqui se eu tenho alguma task, se eu não tenho nenhuma, beleza. Inclusive, issoo aqui se eu tenho alguma task, se eu não tenho nenhuma, beleza. Inclusive isso aqui, na verdade, eu tenho até que alterar, porque ele tem que ser salvado ali embaixo. Então, inclusive depois eu vou até fazer uma correção disso aqui, eu vou colocar um to do, que eu verifico depois. Mas eu tenho que pegar todas as tasks que estão pendentes, se eu estou cancelando o meu projeto, conversei lá com o especialista, eu tenho que cancelar todas as tasks que estão pendentes. As outras que ou foram canceladas ou que foram concluídas, eu não vou mexer. Então, consultei todas. E vou cancelar todas. Então, chego lá, pego a data de cancelamento que eu estou passando ali, eu vou aplicar ela tanto no projeto quanto nas tasks que estão pendentes. Beleza. Se eu passei a data de finished at, então estou querendo finalizar, ele não pode, já está finalizado, completado, ele não pode estar cancelado. E a data que eu estou passando, aqui na verdade, eu acho que até coloquei errado, né? estou passando aqui na verdade, eu acho que eu até coloquei errado, né? Aqui a data de finalização não pode ser menor que a data que eu comecei. Beleza. Aí eu passei a data ali pro finished at e o status de completado. E também eu chego lá e completo todas as tasks que estão pendentes. Né? Tá. Aí, aqui embaixo eu faço o salvamento. E aí, o que vocês acham desse código? No caso, é pra vocês falarem, pessoal. É, pra vocês falarem o que vocês acham desse código. Ele satisfaz? Ele tá legal? Não tá legal? Quais são os problemas? Ele satisfaz a regra de negócio ali, a intenção do que o sistema tem que fazer, mas essa classe projeto aí, né, tem que comer muito feijão pra curar essa anemia aí. Pois é, mas isso a gente fazia aqui é o seguinte, vamos supor que eu tenho Um update aqui, não tem? Eu tenho um update aqui, certo? Então A gente pode colocar assim um método Pra poder Fazer, inclusive ele pode ser até privado Pra ninguém ver que ele existe Pode fazer um start Project aqui Eu posso pegar essa regra de negócio que está aqui. Certo? Até aqui embaixo, até aqui. E eu posso jogá-la para cá. Eu passo o projeto, a data, aí aqui vem a data. Então, eu posso abstrair grande parte desse if deixando apenas a chamada para o meu método. Então eu passei o projeto, passei a data. Se eu fizer isso, eu não vou fazer para todos os outros dois, mas se eu fizer isso para os outros dois, e aí, resolveu o meu problema? Está bom agora? Ainda não, né? Por que não tá? Esse mestre não tem muita responsabilidade. Ele faz muita coisa, tem mais de uma entidade envolvida aí, cara. E me parece que é uma coisa, o projeto é outra. Essa é a responsabilidade da moda, vamos dizer assim, não do serviço em si. Beleza, vamos então tentar fazer uma outra abordagem aqui, quero provocar mais vocês aqui. Então, vamos supor que eu queira então melhorar isso aqui. Então agora eu vou criar um start project ele vai ser público eu tenho também um, colocar complete project também aqui na minha camada de serviço e também um cancel project se eu fizer essa separação resolve o meu problema o seu project. Se eu fizer essa separação, resolve o meu problema? Pegando esse código que está aqui no update todo e segregando ele nos métodos? Assim, no meu ver, com o tempo, esses métodos aí podem vir a aumentar. Hoje eu tenho esses status de projeto. Se aparecer um novo status ou uma nova regra, um novo método. E assim vai indo, vai indo, quando pensar que não tem um arquivo aí, sei lá com quantas mil linhas. Eu vejo isso aí como um problema. Tá, vamos fazer o seguinte aqui, ó. Eu vou deixar esse update aqui apenas como recordação aqui. Esse start aqui, vou deixar ele comentado. Então, vamos voltar aqui pro REST, tá? Vamos voltar aqui pro REST. Tendo em vista que a gente agora está sendo mais intencional, mais expressivo, porque a nossa camada de serviço está manifestando uma intenção melhor do que está acontecendo, em vez de só fazer o update, tá. Então eu tenho esse meu put, meu patch aqui, enfim, como que eu faria pra poder lidar com isso, né? Então, se eu tiver... Aqui em cima eu tenho o nome e descrição, certo? Então, por exemplo, se eu tiver um nome e descrição, ou descrição, a gente poderia fazer aqui uma chamada do project service vamos supor que eu tivesse um update que eu passasse somente esses dois aí agora eu começo a ver as datas então aqui eu passo a minha data que eu iniciei, se ela foi passada se eu passei a data de cancelamento também vou passar a data de cancelamento e agora? o que vocês acham? data de cancelamento. E agora? O que vocês acham? Eu achei pior do que deu do jeito. É, ficou pior ainda. Tendia a crescer infinito isso aí. Pois é, porque da outra forma que estava, estava melhor, porque de qualquer forma estava tudo concentrado no update, mas passava os campos lá, o método se virava para poder fazer as regras de negócio. Se eu quisesse ser mais expressivo, eu estou sendo mais expressivo na minha service layer, mas agora o que está acontecendo é justamente o REST, tá? E o REST, tá? E o REST também, ele está envenenado pela mentalidade do CRUD, porque a gente aprende que a arquitetura REST é você criar... Ah, peraí, então tem que ter um recurso. Qual que é o nome do seu recurso? Ah, o meu recurso chama Projects. qual que é o nome do seu recurso? Ah, o meu recurso chama projects. Tá. Então, é projects e acabou. Se você quiser fazer a criação, você passa um post para fazer o update, você usa o put versus patch ali para poder passar essas informações. E aí, é por isso que quando a gente começa a entender o REST como CRUD também faz com que você modele dessa forma a gente está vendo aqui o problema na cara e acaba fazendo também com que você erre na sua service layer, fora as camadas mais internas então o pensar do CRUD, ele contamina o software inteiro as camadas mais internas. Então, o pensar do crude, ele contamina o software inteiro. Ele contamina o software inteiro, tá? E eu não sei se alguém aqui já pesquisou quando surgiu esse termo crude, né? Na verdade, eu tenho até nas minhas anotações aqui, ele foi popularizado, na verdade ele já tinha sido mencionado na década de 70 por um um doutor, Edgar alguma coisa, não lembro o nome de cabeça mas em 1983 um camarada chamado de James Martin ele lançou um livro Managed the Database Environment, tá? Onde que ele concentra ali as ideias de como que a gente deveria fazer modelagem de banco de dados, e também como que as aplicações deveriam conversar com esses bancos de dados, e aí foi justamente o que ele falando, a gente tem que fazer escrita, tem que fazer leitura, e a gente tem que fazer aquiita, tem que fazer leitura e a gente tem que fazer aqui essas quatro operações básicas, foi aí que popularizou justamente o CRUD que são as quatro operações básicas mas quando a gente está falando de CRUD no final das contas a ideia, ela não surgiu em nível de software ela surgiu em nível de banco de dados, quando a gente em nível de banco de dados. Quando a gente está falando de crude, na verdade, a gente está falando de database. A gente tem que entender que armazenamento, ele é diferente de regras de negócio. E esse traiu o principal problema com que a gente cria, modela, faz o design de sistemas totalmente incorretos. Porque a gente acaba inserindo totalmente nesse sistema, em todas as camadas, porque aqui a gente está trabalhando com arquitetura em camadas, porque eu tenho ali a parte do MVC e tal, a gente acaba inserindo em todas as camadas a preocupação de armazenamento. A gente vai se distanciando do que é negócio. Ah, mas o que o meu software é muito pequeno. Eu não preciso ser tão expressivo. Beleza. Às vezes você está fazendo um software, ele é apenas um editor premium do banco de dados. Um software tão simples acontece, às vezes você tem um software muito pequeno que você está desenvolvendo, ou dentro da sua empresa lá tem um software que não gera grande valor, mas ele é necessário. Você não precisa ter uma modelagem mais rica. Trazer essa modelagem mais rica vai acabar tornando o código mais complicado. Mas a gente já viu aqui nesses casos de uso que a gente já tem algumas regrinhas que são bem peculiares. Um projeto, uma task, eles acabam transitando em estados, a gente tem certas validações. visitando em estados, a gente tem certas validações. E aí, eu quero mostrar aqui para vocês a tese de doutorado do Roy Fielding, para a gente ver como que a gente desvirtua o REST associando com o CRUD. Esse link aqui eu vou colocar ele aí no chat para vocês. Essa aqui é a tese, na verdade, uma parte da tese do Roy Fieldinging foi aí que surgiu o REST, se não me engano, ali em 2002, né? Que é a tese de doutorado dele. Se a gente vir aqui no 5.2, a gente vai ter o estilo arquitetural do REST, né? E aí ele fala aqui... arquitetural do REST. E aí ele fala que a chave da abstração das informações no REST é um recurso. Qualquer informação pode ser nomeada um recurso, um documento, uma imagem, um serviço temporal. Hoje, como está o tempo hoje em Los Angeles? Uma coleção de outros recursos. Outras coisas. Tá? Então, esse pensamento que a gente tem do REST, como tem um recurso ali. Se eu quero atualizar projeto, é barra put. Eu não posso fazer mais nada. É um entendimento errôneo porque a gente tá querendo concentrar tudo no verbo e na verdade, o verbo ele não é tão importante assim no REST tá? ele não é tão importante assim no REST, a gente tá vendo aqui que o recurso pode ser qualquer coisa tá? então, quando a gente coloca Ele não é tão importante assim no REST. A gente está vendo aqui que um recurso pode ser qualquer coisa. Então, quando a gente coloca esse... Deixa eu voltar para cá. Quando a gente coloca esse put aqui, quando a gente coloca esse put, também eu estou fazendo a mesma coisa com o REST do que eu fiz na minha camada de serviço. Eu joguei toda a responsabilidade para um método update, ligando ele com o CRUD, porque, ah, pera aí, estou fazendo aqui a mudança de estado, é update, então vai tudo update. Aí eu coloco também isso no REST. Isso aqui não representa a minha operação de negócio. E aí que vem o conceito de que algumas pessoas já falaram aqui trazido pelo Martin Fowler e também por outros atores que é a anemia do nosso design a anemia é a falta de intenção a falta de expressividade quando eu olho pro meu código Quando eu olho para o meu código, quando eu olho lá para aquele update, tipo assim, eu não vejo expressividade de negócio nenhuma. Eu só vejo preocupações com armazenamento. Está fazendo tudo. A gente viu aqui em funcionamento como que ele concentra mas imagina como que até ficaria difícil pra você poder criar testes de software, né, porque você tá criando lá um teste aí você vai fazer assim, ah, peraí eu quero agora testar o estágio de iniciar num projeto, ah, então tem que passar um started at lá com uma data qualquer e aí você não passa outros campos, não precisa, né? Aí depois você vai espalhando esse update pra do decantelado no momento agora você tá até entendendo o que que tá acontecendo, mas os seus colegas, quando eles olharem isso aqui, você daqui algumas semanas, quando você olhar isso aqui, você vai ficar assim tá difícil de entender isso, né e eu não tô sabendo o que que tá acontecendo aqui e agora me pediram pra poder fazer uma manutenção uma mudança agora sei lá, acrescentou-se um estado novo aí no projeto e você tem medo de mexer nisso aqui. Ou você mexe, e agora é difícil testar. Porque como você tem falta de expressividade, e aí entra todas as boas práticas de orientação ao objeto aqui, de solid, principalmente o single responsibility. Eu tenho um motivo para mudança? Não, não tenho motivo para mudança. Não dá nem para falar quantos motivos para mudança a gente tem aqui. A gente tem um monte. Então, a gente acaba estragando o nosso software justamente porque a gente fica ligado ao CRUD e a gente coloca isso até no REST. Ah, mas então, o que a gente poderia fazer para melhorar? O que eu poderia fazer para melhorar? Vamos ser mais expressivos. Vamos fazer as operações de negócio? A resposta está... O especialista de domínio já nos deu a resposta. A gente já tem aqui essas operações, elas deveriam ser executadas O especialista de domínio já nos deu a resposta. A gente já tem aqui essas operações, elas deveriam ser executadas de forma separada, porque isso vai simplificar o nosso sistema, tanto em nível de manutenção, nível de controle dessas operações, e eu posso até delimitar responsabilidade mais pra outros lugares, né? Eu acredito que alguns de vocês estão pensando em DDD e etc. A gente não precisa necessariamente trabalhar com o domínio do design pra resolver esse problema aqui não, tá? Já seria uma outra seara, não tem tipo, DDD aqui seria uma coisa que seria agregada, mas o DDD tá lá na frente, está nas últimas posições. Clean Architecture também estaria nas últimas posições dos problemas desse software. Então, o que eu poderia fazer? Eu poderia criar essas operações de forma separada. Então, agora, quando eu quero iniciar um projeto, eu tenho um barra post projetos passando o id barra start. Poxa, quando você olha para uma documentação do software, você vê que, peraí, eu posso pegar um projeto, eu posso fazer um start, um cancel e um complete, isso aqui muda totalmente o cenário. Isso aqui deixa muito mais claro o que eu posso fazer com esse projeto. Ao invés de ter um put ou um patch, é enorme com 300 opções. Quem aqui nunca pegou uma API de um sistema de pagamentos, de um sistema de CRM, que você vai ter lá o put e o pet com 500 opções diferentes? Você fala assim, tá aqui opcional, né, mas se eu passar essas opções e não passar essas outras, o que vai acontecer no final das contas? Até mesmo pra gente que é usuário do sistema, não fica transparente. Então, isso aqui demonstra, a gente tá falando só de REST, né? A gente tá falando só de REST. Isso aqui demonstra intenção de negócio. Ah, mas eu poderia utilizar aqui um outro verbo? Sim. Se eu quisesse utilizar um PET, ou o PUT da vida, tá vendo que o problema não é o verbo? O problema aqui, no caso problema não é o verbo? O problema é que no caso não é o verbo. A gente se preocupa demais com o verbo pra poder demonstrar a intenção. Mas a abordagem do post ela é muito interessante porque o post não é não representa somente a criação daquele recurso. Mas você está postando, você está publicando. Então, ou seja, estou publicando o start do projeto. Eu estou publicando, quero fazer o cancel. Então, o post representa uma ação que você quer fazer alguma coisa lá no sistema também. Então, eu posso usar ele tranquilamente. Simplifique, torne isso bem simples. E aí a gente acaba tendo também uma situação Que Eu posso às vezes Querer atualizar somente lá o nome E a descrição Posso querer atualizar somente o nome e a descrição Inclusive eu acho que esse aqui Até não coloquei Mas eu poderia então fazer aqui Um app Patch Passo aqui o ID do meu projeto, deixa eu ver se o Copilot vai me dar uma sugestão. Aí tá vendo, até o Copilot tá contaminado com o CRUD, tá vendo? Ele mandou pra mim um monte de coisas, ele não entendeu o que eu quero, eu só quero trabalhar com nome e descrição. A gente pode deixar o patch apenas pra informações que são ali, que não representam nenhuma mudança expressiva, eu tô apenas fazendo uma alteração de fato, essa informação vai chegar lá no database e vai ser alterada. Então eu tenho o patch para essas informações básicas e o post agregado à operação que fica clara no final. Mas isso aqui não vai contra a arquitetura REST? Não. A gente viu ali na tese do Ray Fielder. O recurso pode ser qualquer coisa. Ele pode representar um documento, uma imagem, uma coisa que você quer fazer então o que a gente precisa fazer daqui pra frente é ter um entendimento mais maduro do REST esse entendimento que é o Barra Projects aqui acabou isso aqui é um entendimento pobre eu diria assim, pobre mesmo a gente tá com uma visão radicalista que vai empobrecer a nossa comunicação. Então a mesma coisa eu faço pras tasks. Ah, eu quero criar uma nova task, isso aqui seria muito, todo mundo faria dessa forma, né, barra projetos, barra tasks, eu faço um post ali e passo as informações da task, criei essa task. Beleza. Ah, e se essa task também eu quiser fazer um start nela? Ah, então tem um barra start lá na frente. Então passo aqui um recurso alinhado no REST, post barra projetos, o ID do projeto, barra tasks, barra o ID da task, barra start. A mesma coisa se eu quiser cancelar a task. A mesma coisa se eu quiser... Luiz, está sem áudio. Então, simplesmente eu posso passar essas informações ali. Então, viu aqui que no REST a gente já tem essa contaminação, até mesmo de uma forma radical de enxergar ali os verbos, e tem que ser daquela forma. Não, tá? Vejam aqui a dissertação, tem outras coisas lá também que o Ray Fielding fala. E aqui a gente vê o primeiro problema. Aí quando a gente olha para serviço, já falaram assim, ah, poxa, deve ter pensado em um domain design, uma clean architecture, a gente não precisa disso a princípio também. Sabe por quê? Porque a gente pode simplesmente trabalhar com um conceito que está lá no livro de Enterprise Patterns lá do Martin Fowler. Vou até pegar o link dele aqui, que é uma modelagem de domínio. Quando a gente está falando de modelagem de domínio, não necessariamente nós estamos trabalhando com o domain design. E é aqui que entra o ponto que eu estava falando lá atrás. A gente está utilizando a orientação objeto, mas sem a essência da orientação objeto. Porque quando a gente pega um ORM da vida, a gente acaba fazendo o quê? Um modelo de dados que só tem dados. Ele não tem comportamento. Então, um domain model é um objeto de domínio que incorpora tanto behavior and data. Aqui não tem nada de DDD. Quer dizer, DDD acaba usando esse conceito. Mas é aqui que está a essência da orientação ao objeto que a gente acaba fazendo também com que a anemia aconteça lá, porque quando a gente olha para a modelagem aqui, eu fiz essa modelagem anêmica, está aqui a minha entidade, que eu fiz ali com o typeRM, aí tem a ID no projeto, tem nome, tem descrição, tem as datas e etc, e acabou. E acabou. Eu fiz apenas uma modelagem. Então, fiz aqui apenas uma representação do banco de dados na minha aplicação. A mesma coisa para a tasking. Eu não tenho behavior aqui, eu não tenho nenhum tipo de comportamento. Aí a gente acaba tendo, numa camada de serviço, aquele comportamento que está aqui, a gente está pegando diretamente o objeto e fazendo um setter. Aqui poderia ter um setter, se fosse outra linguagem de programação, provavelmente teria. Então também a gente está perdendo isso aqui, porque quando eu olho para um project cancelled at igual a cancelled at que eu estou recebendo com status, isso aqui é apenas preocupação de armazenamento. Eu não tenho preocupação aqui de comportamento. Meu objeto não tem. Ele está anêmico. Ele não tem expressividade nenhuma também. Então, assim, de certa forma, se a gente pelo menos tivesse usado lá no REST aquela quebra das operações e o software tivesse com as operações aqui separadas, né? Como a gente tem aqui a chamada de cada... Se eu tô iniciando o projeto, eu tenho start, eu tenho cancel, eu tenho complete. Pelo menos isso já seria o primeiro passo, porque pelo menos a service layer, ela protege o mundo externo de afetar as minhas regras de negócio. Mas acontece que como eu não tenho essa expressividade dentro da minha service layer, quando eu precisar reusar essas regras de negócio que a gente chama de independentes, a gente não consegue fazer esse reuso. Porque daqui a pouco, se eu precisar fazer o cancelamento aqui de uma outra forma, mesmo que esteja num método separado, vamos pegar aqui o caso do cancelamento. Eu só consigo fazer o cancelamento utilizando uma service layer, mas a service layer ela não satisfaz necessidades específicas do usuário ela vai orquestrar o meu negócio apenas, a gente vai ter preocupações aqui com cash, com transação com concorrência e outras coisas assim. Então, também, isso me prejudica na minha expressividade. Por isso que a gente pode chegar nas nossas entidades e ter comportamento. Então, quando eu vou criar um projeto, eu tenho aqui uma Factory Method. O construtor, a gente deixa apenas ali para poder fazer uma hidratação. Então, isso aqui representa a criação. Mas a criação que a gente fica na cabeça é a criação no banco. Essa criação, essa criação, ela é diferente do banco de dados isso aqui representa um comportamento de negócio a criação do banco de dados é preocupação restrita como armazenar os dados lá é uma armazenamento do estado do meu objeto atualmente então olha que interessante esse comportamento aqui que ele não tem preocupação nenhuma com o banco, e ele está misturado junto com os decorators do TypeRM, não tem problema nenhum. Mas quando eu olho aqui para o Create, eu estou criando ele, verificando se foi passado a data de início, porque se foi passado a data de início, eu vou iniciar esse projeto, então também eu tenho um comportamento para poder fazer o start desse cara. Faço as validações, faço as verificações. Então, aqui são as regras independentes. São as regras independentes, que, diretamente ali para o usuário, o usuário não está interessado nessas regras independentes, porque o usuário quer salvar, que isso esteja tudo ok, consistente, etc. Então, é aí que a Service Layer entra para poder usar essas regrinhas independentes, juntar isso de forma a satisfazer a necessidade do usuário, porque Service Layer, ela sempre está mais ligada às necessidades do usuário. Um domain model, ele concentra operações de negócio. Entende? Então, eu tenho aqui todas as minhas operações. Ah, eu quero cancelar também a mesma coisa. Eu quero fazer um complete, eu tenho a mesma coisa, mas eu preciso usar DDD nesse projeto? Não, não tem DDD aqui. Só tem um type ORM, tudo misturado. Aqui, a modelagem com as operações. Quando eu olho para uma service layer dessa forma, olha que interessante que fica quando eu vou trabalhar com as minhas operações. Quando eu vou iniciar um projeto que já está criado, eu consultei, passei a data de start. Então aqui, ele iniciou, eu apenas passo lá para o... Aqui é repositório? Poderia ser Active Record, não importa. Poderia ser um Table Gateway, poderia ser qualquer coisa que você quiser para poder fazer armazenamento tem um objeto ali, eu passei as informações e pronto, o alquêncio também é da mesma forma, então agora quando eu quiser até adicionar mais um estado aqui uma mudança representativa, então isso vai representar um novo comportamento que vai lidar com os meus dados dentro do meu domain model, isso vai representar um novo comportamento que vai lidar com os meus dados dentro do meu domain model, que vai ser usado na minha service layer para poder satisfazer as necessidades de usuário. Está vendo que a gente está separando aqui as duas intenções? Eu tenho a intenção de negócio e tenho a intenção de salvar. E é aqui que está a questão de a gente criar sistemas com um design melhor. O que o CRUD acaba fazendo é que a gente pega toda a mentalidade de armazenamento, toda essa preocupação, e traz ela para dentro da programação. Então, a todo momento, a gente não está preocupado em descrever o negócio, em deixar isso expressivo. Quando eu olho para esse código, ele é fácil de ler, ele é fácil de entender. Até uma pessoa que não entender JavaScript vai olhar para isso aqui e vai saber que um projeto está sendo cancelado. Não é complicado de ninguém entender. Ao contrário, aquela outra service layer, se você der pra uma pessoa que tá chegando no projeto agora, quanto tempo que ela vai gastar pra poder entender esse código que tá aqui? Não tem expressividade, ele tem anemia, ele não tem intenções de negócio. Ele tem intenção de update, que é a intenção de armazenamento então assim cuidado quando você for usar um nome update no seu sistema porque é como se você estivesse no abismo e o crude que tá lá embaixo, que é o demôniozinho, tentando te puxar pra baixo. Então quando você tá usando o update, você já tá, tipo assim, você já tá sendo meio puxado por crude. Vocês viram aqui dentro que no project eu tenho um change name e um change description? Eu não tenho esse update. Ah, mas eu poderia ter um update aqui, não tenho esse update. Ah, mas eu poderia ter um update aqui, se eu quisesse representar, então, melhor essa regra de negócio. Tá, às vezes você tem ali alguma coisa muito simples, né? E aí você poderia passar aqui as duas informações e colocar nas variáveis. Tudo bem, tudo bem. e colocar nas variáveis. Tudo bem, tudo bem. Mas isso aqui, justamente, é uma preocupação de armazenamento. Essa palavra, ela é muito ligada. Então, uma coisa que aí, utilizando o DDD, que a gente não precisa de utilizar lá toda a linguagem tática, a gente pode ficar apenas na estratégica, a linguagem que você usa no seu software, eu não estou falando de linguagem de programação, estou falando da linguagem que você está construindo, a forma que você coloca o nome dos métodos e as variáveis, elas mudam totalmente o entendimento do seu software, acaba entrando Clean Code aqui também, do Robert Martin, que a gente tem aulas e aulas dele aqui. O update, ele é um nome muito ruim. Ele é um nome muito ruim. Talvez um change aqui, alguma coisa. Ah, mas a princípio eu não sei o que vai mudar. Tá, então faz o seguinte. Se não tiver muitas informações, coloque change ali, depois você muda. Isso vai ficar fácil. Isso vai ficar fácil. Se você tem um domain model, a manutenção dele é muito mais simples do que um cara que não tem anemia, porque a anemia ela dispersa. Anemia dispersa. Um modelo rico concentra que é o que está acontecendo aqui o modelo rico está concentrando essas regras mais preciosas dentro da própria entidade não tem necessidade nenhuma de a gente usar essas abordagens de DDD Clean Architecture nem nada muitas vezes o que você precisa é justamente você faz um domain model, não dá pra você fazer um domain model, você tá utilizando aí Hibernate, SQL Alchemy, JPA, Doctrine, Eloquente, Entity Framework, com qualquer uma dessas leads de ORM, a gente consegue fazer uma modelagem rica, que é justamente adicionar comportamento dentro dos models. Então, basicamente, o que eu queria passar pra vocês, pessoal, é isso. Lembre-se sempre que o CRUD, ele é um vírus. Ele não contamina somente a área de negócio. Ele contamina o REST, ele contamina o GraphQL, ele contamina também mensageria. Lembre-se sempre que CRUD é preocupação de banco. A gente está aqui no MBA, e todos vocês estão aqui, para poder criar softwares melhores. Para poder criar sistemas que representem, de fato, a linguagem de negócio. Que gerem valor. Aquele sistema que estava aqui, está aqui ainda, na verdade. Ele funciona? Funciona. Mas à medida que ele fosse crescendo, ele iria gerar uma série de percalços, mesmo se estivesse trabalhando com testes mesmo se estivesse trabalhando com testes e se você está aqui no MBA você quer sair daqui pra cá, talvez você até já esteja aqui talvez muito do que eu falei aqui pra você já faça muito sentido mas isso aqui tem que ficar muito claro. Que o CRUD, de fato, ele contamina totalmente o software. A gente precisa de ter uma linguagem que expresse tudo que a gente estiver fazendo. Desde métodos, nomes de variáveis e até nome de pastas também ajudam a você formar uma linguagem bacana pra poder desenvolver esse software. Beleza, meu povo? Show de bola. Show de bola. Gente, espaçozinho pra dúvida antes da gente finalizar. Quem quiser, já sabe, levanta a mãozinha aí pra gente organizar a nossa fila. Não tem fim aí pra todo mundo pensar se quer fazer pergunta ou não. Se quiser, levanta a mão. E aí a gente vai começar aqui com o senhor Fernando. Opa, fala, Luiz. Muito boa a apresentação. Não foi mais uma daquelas de 3 horas Que nem diz quem Mas eu fiquei com uma dúvida Tudo bem Eu entendo o conceito completamente De eu vou realizar uma ação Eu já deixo na rota Claro que a ação é essa E eu passo isso para dentro Nas outras camadas, beleza Uma dúvida. Nesse exemplo, por exemplo, eu vou mudar o status. Então, muda para aquele status, muda para tal. Mas se fosse, vamos dizer, é um endereço, um formulário de endereço do usuário, dados básicos do usuário, você usaria, tipo, um user barra id barra update ou só um post lá no dado dele, já que você está mandando tudo de uma vez mesmo? Ou você deixaria isso mais claro? Como é que você faria nesse caso, já que você está mandando tudo de uma vez mesmo? Tá. Aí a gente precisa pensar também, inclusive até não falei, né? O CRUD pode contaminar também o front-end, porque esse caso seu aí, já tive casos o front-end, porque esse caso seu aí, já tive casos com front-enders, né, que quando eu fiz essa separação, já fiz sistema com essa separação, e aí já me falaram assim, não, mas aqui, deixa eu te falar, na hora que eu vou fazer aqui o meu o meu botão de atualizar lá no meu front-end, eu tô tendo que fazer essas duas chamadas aqui. E aí se torna difícil pra mim poder fazer essas duas chamadas, porque eu vou ter que fazer esses dois tratamentos de erro. Se a primeira chamada, sei lá, eu tô atualizando o nome só e alguma outra coisa, numa outra eu passo somente o endereço, vai ficar complicado. Tá? Então, esse é outro problema também que a gente acaba entendendo no front-end. Se eu estou fazendo update, eu tenho que fazer apenas uma chamada para o back-end e acabou. Por que a gente entende assim? Entendeu? O usuário vê, né? Vamos dizer assim. O usuário ali está né? Vamos dizer assim O usuário ali Tá entendendo que aqueles Aqueles dados estão sendo atualizados De uma forma consistente Ou seja, na hora que clicar Aquele botão terminou de O loading lá, desapareceu Ele sabe que aqueles dados estão de fato Armazenados em algum lugar, tá tudo garantido Mas Como o sistema vai trabalhar com isso, aí é outra história, né? E a gente relaciona tudo isso, tá vendo como que o CRUD contamina? Porque assim, a gente poderia fazer algum tipo de situação, deixa eu pegar aqui a tela de novo, vamos supor, eu preciso de atualizar, nesse caso, todos os dados do usuário ou do cliente ali de uma vez só? Posso ser que sim. Pode ser que sim. Pode ser que sim, a gente tem que considerar isso. Então, vamos fazer um... Um put, um patch, enfim. Barra. Customer. Customer. um put, um patch, enfim, barra, customer, eu recebo aqui, rec e res, tá. O que eu tenho para atualizar? Eu tenho para atualizar nome, telefone, e o endereço, vamos abstrair aqui, eu tenho, né, logradouro, rua, etc. Essas informações aqui. Eu poderia fazer o envio dessas informações? Poderia, né? Fazendo o envio dessas informações, se eu segregar a minha service layer pra poder fazer cada uma dessas operações, vamos supor que eu tenha aqui um customer service, ponto. Change address, né? Eu não mudo de endereço, né? Vamos colocar uma expressão, eu, mesmo que eu tô na mesma rua, eu fui pra uma outra casa, eu não mudo, eu faço a mudança completa eu não estou trocando somente o número eu estou trocando o endereço inteiro certo? então aqui eu passaria as informações pertinentes mas e se eu tivesse uma outra um outro update, aqui um change name um change, sei lá, info basic, estou só divagando, eu não poderia fazer isso aqui. Isso aqui seria pior do que aquela forma que a gente estava fazendo antes. Por quê? Porque uma camada de serviços, ela garante consistência. Então, aqui eu garanto consistência, aqui eu garanto consistência. Mas se eu colocar aqui dessa forma, se esse primeiro executar e esse segundo não executar, então as minhas informações básicas foram atualizadas, o meu endereço não. Aí você vai chegar aqui e vai fazer o que? você vai circular isso aqui como uma transação? você vai colocar uma transação dentro de outra? isso aqui seria pior ainda, tá? isso aqui seria um... nem um cold smell, um bad smell isso aqui seria um, sei lá filme de terror isso aqui, porque a gente estaria delegando controle transacional para a camada de serviço, mas agora esse controle transacional já subiu um nível, ele deveria ficar concentrado na camada de serviço, agora ele está em outro nível. Então isso aqui seria terrível. Então se eu fosse passar essas informações aqui, se fosse passar essas informações aqui, se fosse passar essas informações todas, seria bem melhor que eu tivesse um update aqui, tivesse um update, que lá dentro dele, ele segregasse as duas atualizações. Ele segregasse essas duas atualizações. Se fosse isso, passaria aqui o Hack Body e passaria. Mas para poder atender a esse requisito, mas lá dentro do meu Customer Service, vou colocar Customer Service aqui, eu teria um Customer Service Change Address e fazendo um Customer Service Update Basic Info. A questão é que quando você começa a ver que você precisa mandar informações demais via REST pra você poder fazer a sua operação de negócio, significa que o tal do cold smell, é um cheirinho ruim que o seu software tem que você poderia estar quebrando. Aí que justamente entra o pessoal do front-end. Porque o pessoal do front-end também está agarrado com o crude. E aí se você der dois endpoints para ele poder fazer aquela operação, ele vai chiar. Porque ele quer fazer... Não, eu quero fazer um put aqui, não me interessa. Eu quero fazer esse put aqui e me dar um put que eu passo todas essas informações. Justamente também porque ele está contaminado. Confesso que eu mexo muito no front, ultimamente, estou trabalhando mais com front, e tem isso, de querer fazer só em um, claro, mas também tem aquela questão, né, que no front a gente sempre tenta diminuir a quantidade de requests, diminuir a quantidade de dados que a gente recebe desnecessário e tal, e pensando em performance, pensando em ranqueamento, tudo, não ficaria ruim ter, por exemplo, eu vou atualizar o dado do usuário, disparo dois, três sequestros pra atualizar um form com cinco, sete itens, por exemplo? Será que o programa de performance que você tem na sua aplicação é mais a consulta ou mais a gravação? Eu já não sei, porque eu tô... Aqui eu não tenho nenhum no momento, eu tô dizendo. Não, assim, é um é pra refletir, outras pessoas também podem participar. O que que representa o maior problema de performance no REST? As chamadas de leitura ou as chamadas de escrita? Leitura, né? Pois é, leitura, né? Leitura. A gente pensa no REST tão ligado ao CRUD que a gente pensa, não, tem que fazer uma chamada, aí a gente já tá pensando nesse nível que vai afetar. Vai afetar é leitura, que você tá trazendo lá um emaranhado de um JSON enorme, etc. Enfim, essa escrita, ela estando segregada, ela faz justamente até que você consiga separar equipes, vamos supor que você tem uma chamada ali que está com problema, aí a sua equipe vai mexer somente naquele trecho ou outro que está acontecendo lá, está ok. Mas, obviamente, isso vai fazer com que lá no front eu tenha que tratar agora duas chamadas, ou três que eu estiver fazendo. Mas isso não é um problema, isso não pode ser um problema. Com toda a tecnologia que a gente tem hoje, de lidar com as promessas, de criar uma camada de tratamento de serviços, na verdade, é mais uma preguiça, é mais uma autodefesa do front-ender do que algo que a gente tá... Isso aqui não representa problema pro software, tá? Se alguém discordar, esses três updates aí não vão representar o problema. Ah, mas eu tenho aqui um milhão de pessoas que estão fazendo update ao mesmo tempo. Me mostra esse software aí que ele é 1% do mundo. Normalmente. É porque quando a gente quer fazer uma defesa, aí a gente joga no caso mais excepcional, que normalmente não é o que está acontecendo dentro da nossa empresa, para poder justificar, para poder manter exatamente o que a gente tem agora. Ou seja, a gente está utilizando um pretexto que não faz sentido, que é uma exceção, não é regra, para poder justificar. Agora, o que faz sentido na hora que eu estiver atualizando o usuário? Eu não sei. Aí você tem que ver o contexto, como funciona. O usuário pode atualizar o endereço de forma separada, faz sentido, tem outras informações básicas. Talvez você envia tudo. Quando a gente está falando o customer não é um bom exemplo pelo seguinte, quando você está atualizando essas informações aqui dificilmente elas vão ter uma consequência de negócio ali, normalmente elas vão chegar no banco e vão ser armazenadas diferente de mexer com uma task com um projeto, que quando eu estou fazendo ali uma coisa, ah, eu vou mudar o projeto agora para ativo, completo, tem que fazer estou fazendo ali uma coisa, ah, eu vou mudar o projeto agora para ativo, completo, tem que fazer tais verificações, vai gerar tais eventos. Normalmente, esses updates, que eles não têm consequências ali, você passa mais essas informações aí. Mas quando você tem essas transições, isso aqui já é claro, né? Quando você tem uma transição, isso aqui vai mudar de um lado para o outro e tal, e vai ter determinadas consequências, você já sabe que essas operações de negócio, elas vão ter que estar separadas justamente para que a gente não faça esse software ser mantido depois, porque esse projeto aqui daqui a pouco vai ter um estado intermitente, mas não sei o quê. E aí, se eu coloco isso tudo num lugar só, isso vai concentrar regras de negócio. Agora, o caso de atualização do customer, você vai só posicionar lá as informações e pronto. E aí que vem também... A gente precisa entrar em harmonia aqui. Você tem um cadastro de categoria. Eu preciso colocar comportamento a princípio? Não, não preciso colocar comportamento. princípio? não não preciso colocar comportamento, faz a sua modelagem recebe os dados da categoria e salva seja inteligente na hora de você tomar suas decisões você não precisa, se eu estou fazendo aqui um domain model, nesse cara tem que ser domain model em todo mundo, não você tem um cadastro de categoria com nome e descrição. Aí você tá fazendo, construindo um foguete pra ir até na padaria e voltar. A padaria da sua casa tá no próximo quarteirão. Aí você constrói um foguete pra ir lá e poder voltar de foguete de novo. Pô, calça e chinelo e vai lá e volta. Entendeu a analogia? Fe analogia? Fez sentido? Entendi, acho que faz sim. Só uma coisa que você citou ali que eu fiquei pensando agora, que no caso do custo lá do cliente, você separou em dois, né, por exemplo, o que seria vamos dizer o nome e telefone, o outro que seria o endereço. Ou vamos dizer assim. A gente tá meio que divagando aqui, né, porque assim, seria bom ter um contexto melhor do que a necessidade do negócio. Mas assim, a gente poderia ter uma... Esse customer aqui, normalmente, ele ia só atualizar essas informações. Não teria regras de negócio complexas aqui, teria que ficar fazendo um monte de verificações. Não, estou recebendo essas informações, vou jogar lá no banco de dados. Então, poderia receber e fazer um put. O problema é que se desse customer aqui eu tiver uma outra operação pra poder fazer em cima dele. E aí eu tô jogando ela sempre no put, sobrecarregando aqui, fazendo com que isso se torne anêmico, entendeu? Não, tudo bem. Eu só fiquei com uma dúvida assim. Vamos supor que tem duas rotas, beleza? Uma rota para dado básico, nome e telefone e outra para endereço. Lá no front, no caso, eu não poderia chamar as duas simultâneas, né? Ele teria que fazer o vínculo, né? Teria que, sei lá, guardar o usuário, ter um ID para vincular com o endereço. Se eu estou fazendo um put, poderia fazer simultâneo. Elas não teriam nenhuma dependência uma da outra. Estou atualizando o endereço, posso atualizar meu nome e telefone. Entendeu? Poderia fazer paralelo. Usar lá um promise output, faço um FAT API, um Axel da vida e acabou. Não, não é a sua opção. Não é a sua criação. Não, criação não. No caso de criação, vamos imaginar que, sei lá, eu tenho um sistema de... Acho que é um sistema bom pra poder criar um montarel de coisas, sei lá, um sistema contábil, né? Você vai criar lá alguma coisa de empresa, tem 539 mil campos. A gente poderia modelar o nosso negócio já pensando o seguinte, poxa, o que eu tenho que criar básico ali pra poder operar aquela empresa no meu sistema contábil? Vou precisar dessas informações. Então, no meu create, eu passo informações ali com um grupo bem menor, e aí eu posso ter uma série de patches aqui e tal, pra poder fazer as atualizações nos outras áreas ali, tá vendo que isso acaba permitindo que eu veja melhor o que que tá acontecendo o que que eu preciso, poxa, pra criar uma empresa eu não preciso passar todos os campos lá do meu sistema contábil, eu preciso passar somente esses se eu precisar dos outros, eu vou inserindo depois, E isso acaba afetando também o front-end, porque o front-end vai o quê? Vai acabar criando abas, vai fazer coisas que vai mostrar para o usuário ali que ele pode ir mantendo aquilo ali, adicionando informações ao longo do tempo. Agora, quanto mais a gente concentra tudo dentro de um put, que pode fazer sentido, a questão é essa. Como eu já repeti aqui, pode fazer sentido, mas quando a gente concentra tudo no input, a gente sempre quer ter uma tela, né? A gente quer ter uma tela com tudo. E é por isso justamente por conta do CRUD. Então, nessa história... Essa preocupação é por conta do CRUD. Nessa história que você falou, então, o jogo vira, né? Porque como é que é hoje em dia, primeiro o design faz a tela e depois a gente monta a tela no front e faz API tudo pensando naquela tela, no caso então a gente faz as APIs para depois pensar na tela, nesse caso primeiro a gente faz todo o fluxo do dado para depois pensar como vai ser isso na tela para ser usado, o que eu preciso ter, como eu vou passar isso, em quais etapas, no caso eu vejo que nesse caso, as pessoas que criam esse design, elas não podem imaginar isso sozinhas. É justamente uma falta de representação de outras pessoas envolvidas nesse projeto para poderem discutir, porque a tela é essencial, porque quanto mais transparente, quanto mais intuitivo o usuário vai poder fazer as operações, mas muitas vezes... Ah, estou criando aqui uma tela que tem 500 mil campos. Está linda, maravilhosa, mas, poxa, por que eu tenho que ter esses 500 mil campos nessa tela? Não posso ter ali abas ou alguma coisa que... Pensa em todo tipo de sistema que você vai mexer. Vai lá no GitHub, entra dentro das clouds. Quando você está criando qualquer coisa, normalmente as telas, elas não têm menos informações, e depois que você criou, ela vai permitindo que você vá adicionando novos recursos, vai fazendo... Você percebeu que esses sistemas maiores, eles tendem a trabalhar, eles nunca te pedem todas as informações pra poder criar qualquer coisa que seja? Já pensou nisso? Não, entendi. Só essa mudança, né, porque como eu tô no front, a gente sempre, sempre assim, como eu vou dizer, vem de cima, normalmente, a ordem, né? E o pessoal de cima, normalmente, vê o quê? Eu vejo a tela, vejo o que o cliente pede, monta a tela, e daí quando chega pro desenvolvedor, tanto back como front, já tá pronto. Aí que você vê as coisas, né? Sim. Não, mas assim, Fernando, o que eu imagino é o seguinte. Isso eu vou parafrasear tanto o Paul Guiverno quanto o Evans, no caso agora utilizando o DDD. Você está criando algum tipo de sistema, talvez você não seja especialista ali naquele domínio. Então, por exemplo, se você tiver esse modelo aqui de crude a princípio, para poder satisfazer tempo, para que você já tenha ali um MVP, alguma coisa, beleza. Mas a questão é que esse software tem que ir adquirindo maturidade com o longo do tempo. O problema é que a gente define, ah, peraí, está anêmico? Então vai morrer anêmico isso aqui, não vamos nem colocar comportamento, o problema é justamente esse, que a gente entende o software como um monolito, monolito no sentido assim, monolito é o quê? É uma pedra, não, está criado aqui a pedra, não pode fazer mais nada, então o problema é justamente esse. Vem lá a ordem de cima, mas o software está sendo pensado para ele ser bem mantido ao longo do tempo, vamos está sendo pensado para ele ser bem mantido ao longo do tempo? Vamos planejar agora o software para que a gente possa melhorar essa arquitetura, essas decisões de design que foram embutidas aqui? Eu não vejo problema nenhum criar crudes a princípio para você poder ir fazendo as coisas e tornar mais rápido. O problema é que passou dois anos, o seu software continua anêmico da mesma forma. E aí? Não, obrigado. Deixa eu liberar aí para os outros falarem também. Beleza, show de bola. Vamos lá, galera. Seguindo aí a nossa filhinha indiana, Sérgio, depois o Arthur. Opa, beleza. Primeiro de tudo, boa noite a todos. Parabéns, excelente aula, muito bom. Tocou no assunto aqui, eu particularmente vivencio isso quase todo dia, anemia, é bizarro, fico louco com isso. A Luísa é o seguinte, uma pergunta que eu até comentei aqui no chat, que eu vi dentro das suas, você estava demonstrando no código, com relação a ações, declarar ações como no final da PEF, dentro do seu endpoint. É uma ideia que até eu já defendi muito lá no trabalho, para poder dar uma semântica melhor ao seu REST em si, tirar aquela visão de CRUD e ter uma visão mais dinâmica, que é o que deveria ser. Mas existe uma resistência muito forte das pessoas que têm aquela visão quase religiosa do REST, mas existe uma resistência muito forte da pessoa, que tem aquela visão quase que religiosa do West, do crude, que é as ações post-push-lead, do get, de que você nunca deve botar a ação no meio do PEF, ou no final do PEF. Como é que eu posso contra-argumentar? E assim, a pessoa fala isso e simplesmente encerra por aí mesmo. Como é que eu posso tentar argumentar contra esse tipo de pessoas de que, não, você pode ter uma maior flexibilidade nas suas ações, Reg? O que você pode dar de experiência, de feedback? Sim. O problema da arquitetura REST é justamente um problema que acontecia lá atrás na web. Acontece. Tem áudio isso aí? Ainda não. Não, também não. Não, não, não. Algumas técnicas acontecem. Voltou? Voltou? Voltou. Acho que a minha conexão aqui deu um delay. Deixa eu voltar aqui a tela. Quando você tem um barra criar, tá? Criar projeto, no caso. Por que o R ajuda é porque antes você tinha barra create barra insert barra um monte de coisas poxa é algo muito óbvio né Capitão óbvio aqui vamos ser Capitão óbvio porque eu não preciso ficar passando isso. Ah, eu estou querendo criar, faço um post. Ah, eu estou querendo só fazer um update naquilo aí, justamente o update do customer lá, não tem regra de negócio no espaço dos dados e tal. Aí eu posso usar o put ou o pet, certo? Quando eu quero escolher, eu uso o delete. O problema é que os verbos do HTTP eles foram criados pensando nas operações de representação de CRUD. E um software que tem regras de negócio vai muito mais além do CRUD. O REST por si, com seus verbos, não consegue representar isso. E essa é a primeira justificativa. Essa é a primeira questão. GET, POST, PUT, DELETE, eles não conseguem representar regras de negócio. Eles vão tentar se esforçar. Eles vão se esforçar. Vão se esforçar. Quando você tem... É a situação aqui do projeto. Quando você tem um put, barra project, que você tem campos que podem ser passados e que não podem ser passados ali, que tem que passar uma hora, outra hora, não, isso vai contaminar o software de uma certa forma. Então, vamos pensar que a gente quer fazer um teste, né? Vamos pensar que a gente quer fazer um teste, porque eu estava falando lá, eu quero fazer um teste de... criar... ou melhor, iniciar um projeto, né? Tá. Então, olha que interessante, né? Eu vou ter que fazer aqui um project service ponto update started at passando uma data, se eu quiser fazer esse teste. Aí eu vou ter um outro teste, que é o cancelar cancelaram o projeto que vai mudar não aqui vai continuar a mesma coisa né a gente vê que e não tá aparecendo que esse troço aqui tá é um update lá no SQL só que a gente está transcrevendo isso para o meio do código. Não está aparecendo o que é? Só está faltando o where aqui, né? O where está embutido. Só está faltando o where aqui do lado. E é justamente por... A gente vê que no REST não representa e também na nossa camada de negócios também não tem representatividade da regra de negócio. É justamente a gente está falando da linguagem. A gente tem que pegar a linguagem de negócio e jogar ela dentro do software, que é o que falta da gente. Isso é uma crítica para todos nós, para mim, para o Leonan, para todo mundo. Saber programar é totalmente diferente de arquitetar bons sistemas. Saber programar, você pode treinar uma pessoa, ela pode fazer scripts para poder fazer várias coisas, mas essa pessoa não vai conseguir arquitetar bons sistemas que vão se manter ao longo do tempo, que você vai continuar adicionando novas features que você não vai ter sofrimento, esse software vai se pagar, e você não vai precisar ficar contratando 500 mil desenvolvedores porque você está achando que a produtividade está caindo, é por conta que não tem uma equipe maior de devs, e na verdade é porque o software dá muita dor de cabeça. Aí você adiciona mais devs e você vê que a produtividade, ela cresce muito pouco. Então, assim, a justificativa aqui é justamente essa, que o verbo da HTTP, ele não tem uma boa representatividade de negócio. Não fica claro quando eu estou fazendo um put ali, passando um started at. Passa isso paraando um start at Passa isso pra um leigo Passa isso pra um leigo Leigo, na verdade, ali do sistema, né? Mas que conhece programação Fala assim, fulano, o que isso aqui faz? Você tá atribuindo Uma data de início, né? É Mas o que mais? Quando a gente coloca o start ali Está vendo que a intenção agora ficou mais forte Tem um start Isso deve representar Uma mudança no projeto Então o REST Ele tem que ser usado Mas a gente está usando De maneira pobre Beleza? Perfeito, Lênin. Muito obrigado. Valeu, valeu. Então, vamos agora para o Arthur, depois o Matheus, depois o Wesley e, por fim, o Lucas. Boa noite. Cadê a câmera, Arthur? É porque eu tô pelo celular aqui, tá já descarregando. Deixa eu abrir aqui. Ah, isso aí. Vendo as coisas aqui, vindo pra um lugar sensioso. Você tá na rua? Eu tava aqui vindo jantar com o pessoal, aí acabei e tô na rua aqui. Porque tá muito barulho lá. Manda ver, manda ver. A pergunta é a seguinte. No trabalho lá que está a gente, eu trabalho junto com o Alan também, que está aí. Eu estou trabalhando na parte de imigração e lá a gente está fazendo essa parte de domínio. A gente está colocando as regras de negócio lá e tem um validente lá que autovalida a parte do construtor. Na hora que passa os dados pra dentro ele já faz a validação lá. o stupor. Na hora que passa os dados pra dentro, ele já faz a validação lá. Só que eu fiquei na dúvida quando eu tava fazendo isso, se não seria melhor colocar as regras no TypeRM, lá nos modelos do TypeRM, do que no próprio numa entidade separada. Aí, tipo, as pessoas lá já tinham mais experiência com isso e eles também deixaram separado as regras de negócio do banco, não sei o que e tal. Só que, meio que a gente replica, a gente faz uma nova entidade, digamos assim, meio que um clone da entidade lá do banco, e coloca as regras lá, e depois tem que ficar fazendo vários converters ali, e isso quando vem no relacionamento, tem que estar convertendo pra a entidade de negócio, pra entidade do banco banco e vice-versa, e aí causa bastante conflito nessa questão dos converters. Aí a pergunta já é meio que, o ideal realmente é fazer uma entidade separada, ou como é meio que espelhado, utilizar na própria entidade do TypeRM seria uma coisa boa. Beleza. Aí tem um ponto muito interessante na sua dúvida, que é você ter um conhecimento mais apurado do seu ORM. O TypeRM é engraçado porque ele trabalha com dois design patterns ao mesmo tempo. É difícil você encontrar um ORM que trabalha com dois design patterns ao mesmo tempo. É difícil você encontrar um RM que trabalha dessa forma. Ele trabalha tanto com o Active Record quanto com o Data Mapper. Com o Active Record, você acaba fazendo um extend lá da sua entidade, acho que é Base Entity, né? E o Data Mapper você não estende nada. Você pode utilizar a própria entidade, no caso, né? É. Então, a gente tem um comportamento interessante que pode te ajudar nesse caso. Como ele trabalha com o DataMapper, o DataMapper é um padrão muito legal quando a gente quer expressar essa riqueza do domínio, que a gente pode separar o mapeamento em outro lugar. E você deixa aquela entidade sua de domínio totalmente livre daqueles decorators. Então, tanto pra você poder pegar ela purinha e jogar pro banco e pegar do banco e fazer outra coisa, você não precisa fazer mais conversão. Porque o TypeRM já faz isso automaticamente pra você. Então, dê uma olhada justamente de você fazer a separação do mapeamento, objeto relacional, você vai criar um outro arquivo lá, esquema, não sei o quê, vai ficar um objeto, vai colocar cada campinho, o campo é int, não sei o quê e tal, e a sua entidade vai ficar livrinha. Aí quando você passar ela pro TypeRM, ele vai saber fazer tudo com ela. Tá? Esse é o primeiro ponto. Mas use essa dica também pra outros ORMs que vocês têm, né? Muitas vezes ficar criando essas duas entidades, né? A entidade do ORM, a entidade rica, acaba ficando chato, né? Porque você tem que ficar fazendo essas conversões. Sobre validações, você pode usar uma abordagem que ela vai poder simplificar o que você está fazendo. Muitas vezes, as validações que a gente acaba fazendo, não sei se é o seu caso, acaba sendo assim, ah, eu quero ver se o campo é nulo, quero ver se o campo tem 255 caracteres, antes de fazer, se for esse tipo de validação, é interessante que você crie uma classe pode ser um Zod, usando um Zod usando um ClassValidator usando, sei lá, qualquer outro biblioteca tem 500 mil aí no JavaScript, né e aí você cria esse modelo lá você cria esse modelo com essas regrinhas e deixa mais livre ali o seu domain model a sua entidade, mas aí você tem um método validate lá dentro, que vai usar essa instância da validação pra poder prover, e aí você deixa pra validações mais específicas, por exemplo, aqueles ifs ali, ah, se for tal coisa, não pode fazer, você deixa essas validações mais expressivas fora dessas instâncias de validações mais expressivas fora dessas instâncias de validação, coloca ela dentro lá dos métodos. Tá? Então, entendeu a ideia? Entendi, sim. Valeu. Beleza? É isso que você queria? Valeu. Valeu, Arthur. Show de bola. Baixa a mãoz valeu, Arthur. Valeu. Show de bola. Baixa a mãozinha aí, Arthur. Próximo, Matheus. A Matheus é outro que está sem câmera também. Ah, tá nada. Beleza? Era bait. Beleza, Matheus? É, beleza. Eu sou dev back-end, né? E eu já utilizava essa moldagem aí de fazer as regras em domínio. Eu fiquei só com uma dúvida. Qual que é a vantagem de você utilizar o Factor Method ao invés de você utilizar o Construtor? Ah, legal, legal, legal. Isso também é uma boa dúvida. Vamos lá. Ah, legal, legal, legal. Isso também é uma boa dúvida. Vamos lá. Vou pegar aqui a minha entidade que tem a separação, né? Ela tem o método construtor e ela tem o método de criação. Por que é legal fazer essa separação aqui? Porque o construtor, ele vai ser usado em alguns momentos no teste, você precisa criar a instância daquele objeto, ou quando você está recuperando do banco de dados. Aqui, no caso, esse construtor não está nem sendo utilizado, porque o TypeRM já faz toda a hidratação. Mas normalmente a gente deixa o construtor para poder fazer essa hidratação, porque às vezes você está fazendo alguma coisa mais específica para poder trazer esse dado, e o construtor serve para poder fazer essa hidratação, porque às vezes você está fazendo alguma coisa mais específica para poder trazer esse dado, e o construtor serve para poder carregar. Então, hidratar a entidade é diferente da operação de negócio de criar. A gente faz justamente essa distinção, porque daqui a pouco, se a gente precisar de trabalhar com conceitos mais de alto nível, por exemplo, como eventos, trabalhar com conceitos mais de alto nível, por exemplo, como eventos, aqui eu registro um evento de criação do projeto. O construtor não faz, o construtor não criou, ele só está gerando uma instância daquele objeto. Entendeu a diferença? A operação de negócio, ela pode trabalhar com eventos e com outras coisas. O construtor só serve aí pra gente poder ter uma instância desse cara. E vai sentir. Em outras linguagens de programação como o Java, né? Isso eu gostava muito do Java. A gente tem sobrecarga, né? Eu posso ter um create do Java, a gente tem sobrecarga, né? Eu posso ter um create, isso no JavaScript não pode, posso ter um create passando parâmetros diferentes. Se eu tiver dois métodos iguais com parâmetros diferentes, eu posso. Isso aqui eu adoro no Java, porque aí você pode ter múltiplos factory methods pra poder satisfazer a... Ah, peraí, eu posso criar o projeto assim, mas posso criar o projeto dessa forma também. Aí você pode fazer essa separação, essa distinção, e fica legal. Infelizmente, no momento, o JavaScript não tem, né? Se você quiser criar um... precisar fazer aqui uma outra criação, aí você coloca um Create XPTO da vida, né? Ou um nível mais ainda... Um nível mais abstrato ainda, você poderia ter uma class factory, às vezes, sei lá, é muito complicado ficar criando esse objeto aqui, aí você cria uma class que é uma factory para esse cara e talvez até um builder. Está vendo como que às vezes pode entrar o design pattern na questão aqui, a gente não precisa entrar naquela paternite, não, eu tenho que usar builder, class factory mas não sei, você tá usando pra quê? você tem algum problema? não, você não tem problema, você tá usando isso aqui tornando seu software mais caro, mais complicado e depois você coloca a culpa ainda no design pattern você diz design pattern que é errado beleza? mais complicado e depois você coloca a culpa ainda no design pattern. Esse design pattern é errado. Beleza? Beleza. Boa de bola. Próximo é o doutor Wesley. Pegando o áudio aí? Vamos lá. Perfeitamente. A minha pergunta, ela é meio que a ideia, ao contrário de usar padrão. Tipo, quando eu entendo essa ideia de change methods, change method não, change name, change methods não, change names, change aggressive, etc. Eu nunca tive um problema em criar métodos assim, porque inclusive eu até prefiro colocar uma responsabilidade própria para cada situação, maravilha. Eu também pessoalmente não gosto muito de REST justamente por causa dessa má vista que a gente tem disso. Não que eu goste dele, mas por causa dessa fama mesmo. E a mesma coisa pro CRUD. E aí eu gosto também da ideia de eu faço tanto back-end como front-end e quando eu vejo a experiência do usuário final, a pessoa que vai usar o meu sistema, não quem está desenvolvendo, eu quero passar a melhor experiência para aquela pessoa. Porque eu também não posso passar uma experiência tão agradável quanto para quem desenvolve comigo. E aí eu criei uma ORM de serviços, de classes. E eu queria perguntar, porque ela entra exatamente nesse mérito de atribuir e delegar de mais ou de menos, ou separar de mais, no caso. Então, por exemplo, é como se ele fosse um intermediário entre o front-end e o back-end. Quando eu criei isso, funciona tanto para, por exemplo, o aplicativo manda de um jeito, enquanto o web manda de outro, sabe? Então ele intermedia. Minha ideia surgiu dali. E se eu transformasse isso num intermediário dinâmico? Ele é quem vai escolher qual é a função que ele vai pegar do back-end a partir do que veio do front-end. Então, todas as funções que o back-end cria estão lá, estáticas, bem parecido com o que você colocou lá na tela, sabe? Change isso, change aquilo. Só que o usuário, nem o back-end, nem o front-end escolhem qual vai ser chamado. Esse ORM que eu faço de serviços é quem vai escolher quem. Então, não é uma transação de banco, mas tem a função commit, então o que acontece? Nesse intermediário, no caso, a pergunta, no caso, não é uma pergunta, é uma opinião do quão isso é viável ou não dentro desse tema, sabe, de hoje. Então, vamos supor, ao invés de iniciar uma transição de banco, onde, ah, change name, mudou o nome no banco, transição, travada. E aí, no final, ah, se sucesso comite. Não. Ele gera tudo e aí vai lá, change name, change isso, change aquilo. Sem coisa, ele vai fazer 100 operações na memória ali. E no final, se eu enviar o commit, ele cria a query absoluta só naquela hora, entende? É uma única query. Esse, eu não sei pronunciar, mas esse mirror, né? Tipo, como você acha que ele é viável? A intenção dele é justamente criar uma experiência melhor pra quem desenvolve comigo, sabe? Tá, acho que isso seria basicamente uma, você criou um Java server faces, né? Tá me parecendo é basicamente isso que você criou? Mais ou menos. Ele cria a... a ORM... A ORM ainda cria o... a query, tipo, sozinho, sabe? Então, eu peguei o... No caso, eu gosto de trabalhar com MySQL, né? Então, eu peguei o... Como que uma ORM funciona e como que uma URM funciona e como que uma não URM funciona e como que é a ideia de serviços ali. E uni todo mundo e uni aquela ideia de programação funcional onde você vai ter um arquivo com três linhas só porque é uma coisa única ali, sabe? Responsabilidade única. Então, ele é um sistema muito dinâmico para escolher quem vai chamar. Então, vamos supor, não tem essa coisa de if username se chama função name. Não, ele entende que o name já traz o método name. E quando ele traz o método name, ele retorna aquele resultado. E no final do commit, ele gruda tudo. Entendi, entendi. Essa abordagem sua, eu acho ela muito útil, como existem várias, que é justamente para você poder diminuir o custo de criação de funcionalidades, de software, que são diretas. O problema desse tipo de abordagem, quando você tem processos de negócio, que você tem muitas validações, muita variação, esse tipo de procedimento, mesmo que você vá desenvolvendo, vá maturando, ele não vai conseguir atender a todas as regras de negócio. Então, por exemplo, em cenários em que você tem processos de muito risco, com muita variação de regras, é ruim você usar isso aí justamente porque vai te engessar pra você poder expressar essas regras de negócio entendeu? Quando você tem cenários por exemplo, eu quero fazer aqueles crudes mais simples, aquelas coisas mais diretas tem por que você ficar fazendo, demorando 3 horas pra você poder ficar salvando 4 campos no banco de dados? Poxa, não isso custa caro. Seu tempo ali que a empresa tá te pagando, tá valendo de ouro. Então, se você usar qualquer tipo de abordagem, eu tô usando esse seu Carry Manager aí e tal, ótimo. Eu acho excelente. Agora, quando você tem justamente esses cenários aqui, se você usa isso aí, como que eu vou representar ali uma validação de transição de estado de um projeto que pode ficar iniciado e ir pra completo e talvez publicar um evento de que o projeto agora tá completo. Como que você vai agregar isso dentro do que você fez, né? Aí você pode pensar assim, poxa, não, vou fazer você vai criando um monstro para atender todas as situações, e é justamente o que software não deve fazer, porque software não consegue atender tudo, framework também não consegue atender tudo. Porque quanto mais a gente tenta atender tudo, mais complexo se torna, e a gente vai divagando. Você criou um cara que vai lidar aí com as carries daqui a pouco esse cara tá lidando com um evento, esse cara tá lidando com um monte de coisas e aí você nem sabe mais o que que isso faz e vai se tornando inviável então assim, eu acho super saudável, ótimo usar essas soluções desde que não sejam em processos que são valiosos, em processos que têm muitas regras de negócio, que você tem que garantir inconsistência, que você tem que demonstrar expressividade, entendeu? Perfeito. Beleza? Show de bola, gente. Continuamos aí com o Lucas e finalizamos com o Felipe Alô Sofit eu presente, boa noite tudo bem, pessoal? a minha pergunta surgiu com a resposta da pergunta do Fernando, na verdade sobre quebrar em várias requisições eu tentei fazer isso uma vez e eu tive muito, era um aplicativo mobile, e eu tive muito problema de as coisas ficarem incompletas, principalmente celular. No caso, era um aplicativo que o cara tirava pedido na zona rural. Então, às vezes, a internet não ficava boa, ia um pedaço, não ia outro, e assim. E como que eu resolvi? Também é mais uma opinião do que uma pergunta. O que eu resolvi foi, eu criei uma lógica considerável no front-end pra ele saber, aí ele montava um JSON muito rico pra ele informar pro back-end, ó, esses aqui você vai chamar, atualização. E aí, com base no JSON que eu recebia, que ele era bem verboso, eu sabia que eu tinha que chamar o change name, change address etc, etc, mas eu recebia tudo de uma vezada só porque aí eu garantia que eu não ficava no meio do caminho, porque no meu caso eu estava fazendo um pedido, então era ruim se eu não tivesse o pedido completo então é mais uma opinião de como tratar essa dificuldade que eu também concordo, é mais interessante você ir jogando várias requisições, mas às vezes tem esses complicômetros. Não, com certeza, isso aí é totalmente válido. Você pode ter, a gente estava conversando ali muito de um cenário olhando muito para a web, mas você pode ter um cenário mobile com várias restrições de conexão e outras coisas que há chance de acontecer um erro com aquilo ali. Então, o seguinte, a gente tem a service layer. Ela tem que atender se eu tiver uma outra camada de REST para poder atender o mobile. Então, o que a gente tem que fazer é as nossas regras mais preciosas, elas não deveriam mudar por conta de cenários diferentes de meios de comunicação que estão acessando. A questão é justamente essa. Porque senão, aí entra uma outra história que é justamente o meio de comunicação está invadindo um domínio que não é dele. A gente cria uma service layer justamente para poder separar a arquitetura em camadas. Eu tenho a camada de comunicação do REST e tenho a camada de negócio. Justamente para que elas tenham um limite. Elas têm uma fronteira, um muro entre elas. A gente pode conversar, mas desse muro aqui ninguém passa. É justamente isso. Então, nesse caso, perfeito. A gente tem que, sim, a questão é adequar aos outros cenários também, mas as nossas regras de negócio, principalmente as independentes dos objetos de domínio lá, elas têm que estar independentes. Vou criar uma regra lá justamente porque o mobile agora, não, poxa, o nosso domínio tem que transcrever essas necessidades. Perfeito. Então eu posso deixar separado no back-end e mandar uma coisa só no front-end deles que eu não invado essa, não estou mandando um update e se vira aí com os campos. Eu tinha uma certa separação no final. Mas tá bom, beleza. Era mais uma opinião. Você tem um controller para mobile, você tem um controller para mobile que vai aceitar essa outra variação dessas informações para satisfazer essa restrição de negócio. E aí, esses dados aí, a gente poderia ter aquele update lá, aquele update que ele vai servir para o mobile, mas ele serve também para a situação, eu quero atualizar tudo de uma vez. Então, paz, ele vai conseguir fazer. Então, olha que legal, né? Eu tenho os processos de negócio separadinhos lá dentro, mas tem um updatezão também que poderia atender. Beleza. Desses métodos que eu tenho, desses métodos que eu vou chamar quatro métodos dentro desse update que está na Service Layer. Lá dentro eu delego a questão toda transacional. Só vai acontecer tudo se tudo de fato for persistido. se alguma coisa falhar descarto tudo, o controle está tudo dentro do service layer o controller só está chamando aquele controle do mobile só está chamando aquela situação perfeito, beleza maravilha obrigado Felipe, vamos lá opa, boa noite a vocês boa apresentação perdi um pedaço no começo de bola. Felipe, vamos lá. Opa, boa noite a vocês. Boa apresentação, perdi um pedaço no começo, então espero que eu não esteja falando nada errado aqui para esse pedaço que eu perdi. Está gravado. Está gravado? Bom, bom. Então, eu vou falar uma pergunta que entra um pouco o que o Fernando falou, um pouco o que o Lucas falou, até um pouco o que o Wesley falou, porque pelo que você falou do hash, de você transformar o hash, o cru de se transformar no hash e juntar os dois, não é uma boa prática? E daí eu comecei a pensar um pouco no que foi desenvolvido na empresa agora recentemente com o sistema distribuído. Foi desenvolvido para o aplicativo uma BFF, onde entra aquela questão de você ter dois requests do app para fazer dois updates. Isso não vai acontecer, porque a BFF vai ser responsável por receber esse request, e ela vai fazer o tratamento da informação para mandar para os serviços necessários para fazer o update na base. Mas daí aqui entrou um ponto que fica um pouco na dúvida, porque a BFF recebeu, por exemplo, um formulário que era em três ou quatro etapas, que tem várias informações, e nesse formulário, às vezes não tem todas as informações do usuário imediato, ou tem. E foi feita uma service que ela é só responsável por receber a informação e controlar a base de dados e nessa service foi esse endpoint de patch, que é onde você vai mandar todos os dados e só vai salvar o que você recebeu. Aí entra aquilo que você comentou, você tem um endpoint onde você vai salvar todos os dados, mas você vai salvar só o que você recebeu. Mas só que a regra de negócio não está naquela service. Aquela service é responsável simplesmente por acessar a base de dados e fazer o SEIS. O quão certo ou errado, não existe certo e errado em muitos casos, o quão é bom uma arquitetura nesse sentido, onde você tem uma service somente responsável pela base e a regra de negócio fica separada na BFF. Existiu até uma situação onde teve um time que fez até um serviço no meio, que é um core, que ele é o responsável pela outra regra do negócio, que não fica nem na BFF nem na service. Estou pensando no sistema distribuído, o quão o hash entra nesse esquema aí. Isso que foi explicado hoje. Beleza. Nesse caso, então, você tem, por exemplo, vamos pegar aqui para todo mundo entender, você tem uma chamada que você passa ali, pega um cadastro de cliente e aí você recebe lá 50 campos, aí você manda 20 pra um lugar e 20 pro outro. É possível. Tá. Um problema que vai acontecer nesse cenário é que se você tem chamada da HTTP pra um lugar e pra outro enviando, você tem risco de inconsistência aí, né? Sim. Porque se o primeiro fizer e o segundo não, você fez a sua operação pela metade. Você fez a sua operação pela metade, e aí, como que a gente vai tratar isso? Como que vocês fazem hoje pra poder, quando acontece esse cenário? Tem vários casos por usando filas, então não é um update síncrono, então a informação vai chegar, vai passar na fila, e a fila vai processar, e o usuário vai receber uma notificação depois, e deu sucesso. E existem os casos síncronos, esses casos são um pouco mais complicados, como você falou, você deu um erro aqui, a gente tem que ter um tratamento pra fazer o revert depois, porque inconsistência sempre acontece. Aí, nesse caso, é um pouco mais complicado. Tem casos até que é manual. Você der um pau que ninguém esperava ali no meio do caminho, a gente salvou uma informação e a outra não, fica incompleta, tem que vir manualmente fazer a correção depois, ou cancelar tudo que foi feito para o usuário ter que começar de novo. Ah, nesse caso, então, você tem essa service que ela se comunica com esses dois serviços? Você está fazendo HTTP, se chama de Gator? O que vocês estão fazendo dentro? Tem a BFF. Nesse caso, tem um time que tem um serviço de core. É síncrono. A BFF recebe, ele chama o core e o core chama a service que acessa o banco. Então, a regra do negócio está no core, mas a BFF que recebe a informação do front, que tem todo o tratativo da autenticação e tudo, ela repassa para esse core onde vai fazer a tratativa de negócio, a regra de negócio, e esse core vai mandar para salvar onde precisa ou buscar a informação onde precisa a partir de outros serviços. Então, nesse caso, o problema que a gente tem é justamente a separação das regras, porque essa validação ela deveria estar numa camada de negócio. Pelo que eu tô entendendo, essa validação, ela tá fora da camada de negócios, né? É, ela tá no serviço de core, que é onde tá as regras de negócio. Ah, tá no serviço de core. E aí dentro desse serviço de core, você tem dois HTTPs? Ele vai receber HTTP e vai repassar HTTP em alguns casos. Ele vai receber o HTTP lá do outro serviço e vai chamar o outro HTTP pra pegar a informação ou pra salvar a informação. Tá. Uma delas é muito importante, né? Porque é provavelmente uma que você vai fazer primeiro, né? Sim. Não é? Por que as duas tem que ser Consistentes ao mesmo tempo? Já pensou nisso? Por que as duas tem que ser consistentes? Eu tenho uma que é importante A outra não poderia ser processada Uns segundos depois Via fila? Em alguns casos sim Então Porque uma coisa que às vezes Segundos depois, via fila? Em alguns casos, sim. Então, porque uma coisa que às vezes a gente pensa, a palavra tempo real, ela é horrível, tá? Porque a palavra tempo real, a gente imagina que tem que acontecer naquele momento, mas quando você conversa lá com o especialista do setor, você fala, mas o tempo real pode ser uns 10 segundos? Pode. Tem problema não. Às vezes pode ser até dias, dependendo do que for. O problema da gente trabalhar justamente com essas chamadas é justamente a resiliência, tratamento de erros. A gente poderia ter o processo de negócio sendo iniciado, fazendo a persistência dos dados mais importantes, e aí eu envio para uma fila para aquilo ser atualizado, e nesse caso, então, o usuário já teria a resposta mais rápida, quando, olha, os seus dados ali foram criados, a gente está terminando o restante. Aí poderia receber uma notificação via e-mail, alguma outra coisa nesse sentido, mas nessa situação aí, em alguns segundos depois, provavelmente, o outro processo de negócio já estaria feito. E se não tivesse feito, a gente iria reprocessar até isso acontecer. Então, nesse caso, a gente resolve tanto o problema de gargalo nessa aplicação, porque você estaria fazendo o processo de negócio ser processado mais rapidamente, livrando uma thread web, permitindo que mais pessoas façam requisições, até economizando o software, e tendo mais resiliência. Obviamente você está fazendo uma dispersão da sua regra de negócio, mas justamente para poder ter menos problemas com os erros que podem acontecer, porque rede rede falha tipo assim, não é se vai falhar, não, vai falhar uma hora, vai falhar às vezes não é o sistema que tá fora do ar a rede em si ali não teve a conexão, né, e isso acaba gerando vários problemas, então quando a gente tem esses cenários, sempre quando a gente puder fazer uma etapa do processo de negócio ou várias etapas de forma assíncrona, é o melhor dos mundos. Entendeu? Sempre, sempre. Sempre quando você puder ser assíncrono, seja. Isso é uma coisa que eu percebi ali, que teve alguns casos que deveria ter sido assíncrono e pelo tempo curto, como sempre no desenvolvimento, que nunca tem tempo ficou assíncrono, então uma evolução provavelmente vai ser aos poucos migrar e ser mais assíncrono para a gente ter o que a gente falou, deu problema, reprocessa até funcionar e o usuário não é onerado, hoje existe um caso onde um errinho simples pode onerar um usuário e deixar o cara não conseguir fazer, ou ter que tentar de novo. Então, isso é uma coisa que realmente, com essa divisão de responsabilidade, é mais fácil acontecer, porque a gente tem vários microserviços ali que você é comunicando, síncrono. Então, um falhou, você vai parar lá na ponta, o cara recebeu um erro e você decidiu errado. Então... Vou pegar aqui um processo, eu não sei se alguém que trabalha nas Casas Bahia, mas é só pra gente poder brincar, né? Imagina que você chegou lá nas Casas Bahia, do centro da sua cidade, e você foi comprar uma televisão lá de LED de 40 polegadas. Aí você chegou lá no vendedor, ah, eu quero essa televisão aqui e tal, gostei dela. Aí o vendedor vai pra você, vai com você num totemzinho, um computador, aí ele vai lá, pega o seu nome, Felipe e tal. Você vai pagar como? Ah, você vai pagar no cartão, etc, tá. Aí ele deu um enter lá, né? Aí você vai lá pro caixa. Aí você chegou lá na menina do caixa, passou o cartão, dividiu em 12 vezes, etc. Aí, ah, tá aqui o papel? Vai ali na expedição ali pra você poder fazer a retirada da sua televisão. Não sei se, tipo assim, as pessoas fazem isso ainda, né? Apesar de todo mundo comprar basicamente tudo na internet. Aí você percebeu que esse processo de negócio aí, ele não foi síncrono? Se ele fosse síncrono, na hora que o vendedor desse o enter, a televisão aparecia na sua mão. E você já ia embora. Isso seria síncrono. Mas você teve que ir, a atendente lá, às vezes, tem que verificar algumas coisas. Aí, quando transporta para o mundo do software, a gente imagina que tem que acontecer tudo de uma vez. No mundo real não é assim. Para valer, não é assim. Processos de negócio, às vezes, demoram dias para que você consiga terminar alguma tarefa. Então, a gente tem que entender essa ideia do tempo. O tempo real é muito ruim. A gente do tempo, o tempo real é muito ruim que a gente sempre imagina o tempo real é agora mas o tempo real muitas vezes pergunta para os envolvidos pode demorar 10 segundos? ok, então agora a gente vai colocar isso numa fila você ganhou um monte de nossa, você vai ter tantos benefícios em colocar esse processo numa fila. Por que o Valgvernon, inclusive, não sei quem já viu o módulo de DDD, ele fala que dentro de um application service, você só deve trabalhar com um agregado. Essa é a regra, uma das regras dos agregados. Você deve trabalhar apenas com um. Ou seja, ali naquele processo de negócio, você vai trabalhar apenas com um agregado. Pode envolver às vezes várias tabelas, mas é um agregado só, mas eu tenho que fazer outra coisa. Então, delegue isso a um evento que, se possível, processe isso de forma assíncrona numa fila. Porque quando você faz essa dispersão, você tem mais controle sobre resiliência, sobre capacidade de processamento e também, essa dispersão tem o benefício de quando eu atualizar, fizer alguma coisa nos dois agregados, dificilmente vai ter um impacto que eu mexa num e vai ter vai afetar no outro. Agora, se eu mexo com muitos agregados no meu processo de negócio ali, dentro do meu método do Application Service, o que vai acontecer? Possibilidade, apesar deles serem independentes, se eu mexer numa coisa como eles estão ali dentro, pode ser que desica nos outros, né? Porque eles estão muito ligados, porque eles estão dentro do mesmo método de negócio. Então, por isso que é bom a gente sempre colocar num handler, trabalhar com eventos, se possível, fazer de forma assíncrona, porque aí você gera essa independência. Eles ficam presos aos eventos, o que é ótimo. Porque evento é sempre uma forma de a gente se reagir a alguma coisa que está acontecendo. Mas os agregados em si, eles acabam não se conhecendo. Agregados diferentes fazem parte do mesmo processo de negócio, eles não se conhecem, eles só conhecem os eventos que vão acontecendo à medida que o meu processo de negócio vai avançando. Tá? Fechado, Felipe? Era isso? Tô de bola. Beleza? Tô de bola, galera. Então, você tá no livro, ó, o Jefferson aqui, Luiz, perguntou se isso que você falou agora há pouco está no livro vermelho ele está mais no vermelho ele está mais no vermelho, porque no azul o Evans não fala muito de forma técnica, quando ele vai entrar na modelagem tática, ele dá alguns exemplos lá de Java, mas a gente pode, pelo menos assim, para mim, o melhor livro de DDD é o vermelho. Inclusive, eu recomendo que você leia o vermelho, depois o azul. Apesar do vermelho ter sido criado depois, porque o vermelho, ele é muito mais técnico. Ele vai te dar uma visão de como que as coisas vão funcionar na prática, aí depois, quando você lê o livro azul, sua cabeça vai estar mais aberta, se você lê o livro azul, como ele tem muitas coisas de linguagem ubíqua, POs, gerentes de software, aí você vai ficar meio boiando, né, apesar que tem o, se você não viu o módulo de DDD aí, né, aí fica boiando mesmo, se você viu o módulo fica mais claro, mas é sempre recomendado ler, a minha visão pelo menos do vermelho primeiro e depois o azul, não é o verde apesar que tem um livro verde do Vernon, que é o Destilando DDD também, se vocês quiserem acrescentar, e o livro do Coronove também pode pesquisar, acho que é assim que se escreve Coronove também. Pode pesquisar. Acho que é assim que se escreve. Coronove. Também é muito legal. Ele reúne tanto... Ele é um livro que reúne melhor estratégia e tática ao mesmo tempo. Porque o livro vermelho não se concentra muito no design estratégico, que a gente viu lá, que é a parte de você fazer o mapeamento dos contextos, determinar os subdomínios e tal, então do Coronov também, mas o problema do Coronov é que ele é apenas totalmente em inglês, né? Aí se alguém tiver dificuldade, aí não tem tradução no momento, mas é um livro bem bacana também. É isto. Fechado, então, pessoal? Vou pedir pra que vocês avaliem aqui novamente a nossa dinâmica. Vou botar aqui no chat. Vou colocar lá também no Discord. É muito importante para que a gente mantenha ali um padrão e saber também se a gente está indo para um local que vocês querem ou não. No mais, novamente, muito obrigado, Luiz, pela participação. Muito obrigado Luiz pela participação muito obrigado a todos pela participação Vladikosnov é isso Luiz? eu nem arrisco Coronov vai ficar sendo Coronov eu nem arrisco pronunciar esse negócio eu já escrevi errado ali mas é isso aí mesmo é esse nome aí enfim esses nomes Mas é isso aí mesmo. É esse nome aí. Esse nome aí. Enfim. Esses nomes, assim, você tentar pronunciar nome alemão, polonês, ucraniano, russo, assim, nem esquece. Croata, né? Você tem que... Enfim. Tem que saber bastante, por saber bastante caso não de letra não faz sentido mas é isso galera exatamente muito obrigado então galera a todo mundo que participou aí lá no calendário a gente já tem uma nova data também, depois eu coloco mais algumas outras lá façam ali esse formezinho pra mim, por favor. É bem rapidinho. E encontro vocês na nossa próxima dinâmica. Fechado? Valeu. Um abraço. Até mais. Tchau, tchau. Valeu. Boa noite.