E aí por fim ele vem aqui na na na page store orders API e aqui sim é o ponto que eu comentei que pode ser que traga algum problema de performance de eficiência para sua topologia e aqui alguma oportunidade que pode ser avaliado até de repente ordens API de forma cascateada onde eu faço é uma duas três quatro cinco seis sete oito nove dez e várias várias 11 12 ou seja eu chamei aqui para chamar de 12 só não contei errado chamei fiz 12 requisições de forma cascateada pro serviço de pra consultar os produtos. Então, eu chamo aqui eh passando aí de do produto o produto um, chamam de novo passando o produto dois, chamam de novo passando o produto dois chamam de novo passando o produto três e a que ele chamou de novo na verdade ele chamou pro mesmo produto, né? Aqui é uma uma outra oportunidade que pode ser avaliada. Pode ser que uma tem a pode ser que o mesmo produto apareça mais de uma solicitação. Será que eu não poderia ter feito um mecanismo de pra pra que eu não fosse ter feito um mecanismo de caching para que eu não fosse de novo na API de orders consultar o mesmo produto aqui também de novo uma oportunidade de arquitetura que o tracing consegue nos revelar eu estou consultando o mesmo produto nessa requisição aqui e consultando o mesmo produto na primeira é porque eu tenho claro dois produtos apenas ali eu tenho, claro, dois produtos apenas ali, eu estou trabalhando com dois produtos, mas pode ser que o caso produtivo revele esse comportamento. Então, eu poderia economizar aqui pelo menos uns 40 milissegundos por conta dessas consultas repetidas. E aqui vai até o final com esse comportamento, consultando por conta dessas consultas repetidas. E aqui vai até o final com esse comportamento, consultando basicamente os mesmos produtos todas as vezes. Bom, fiz duas modificações aqui na aplicação, com base no que a gente aprendeu do trace. Aqui na rota de find products, na classe order products cross-cut, eu implementei uma notation de find products, na classe order products crosscut, eu implementei uma notation de cacheable. E aqui no store application eu estou utilizando enable caching. Não estou utilizando um cache distribuído, que seria o ideal nesse caso, utilizar um redis, alguma outra solução, memcached, ou outra solução de caching apropriado, mas aqui queremos até equilibrar custo-benefício. Aqui eu preciso fazer um caching rápido em memory mesmo na aplicação, eu vou ocupar um pouco mais de memória da aplicação local em troca de redução de latência. E aqui no controller, em vez de fazer a busca depois que eu faço orders para listar todas as ordens que eu consultei na base na rota de get e faço flat map para consultar todos os itens eu utilizo o o paralel aqui do próprio do próprio enfim do próprio string aqui do java 8 string do java aqui e aí eu em cima desse desse desse paralelo eu itero aqui no for it então vamos testar se isso vai funcionar apropriadamente bom tô com a aplicação rodando vou parar eu vou compilar as aplicações aqui com docker-compose vou pausar o vídeo para não ficar extenso, esperar terminar de compilar. Terminou de compilar, vou agora subir novamente com o Docker Compose App. Não vou subir em background, quero olhar os logs da aplicação. Enquanto sobe, vou pausar o vídeo para não ficar muito extenso e a gente já volta. A aplicação terminou de subir, vamos acessar a rota do post do insomnio aqui fazer uma requisição de post até para validar com mais assertividade porque geralmente a primeira requisição tem o tempo de warm-up da aplicação e vamos chamar a rota de get e validar se as alterações que fizemos surtiram efeito. Observe que a aplicação retornou agora em 630 milissegundos, vamos acessar o Jager, eu até resetei aqui tudo pra gente garantir que está pegando os dados mais frescos aqui e vamos consultar a rota de observe que a rota de ela não teve nenhuma interação com o serviço de eh o serviço de de de de produtos ali, né? Ela porque os dados estão na própria aplicação. Como eu fiz a criação da passando ID de produto, eu precisei consultar o dado do produto e coloquei um annotation de um annotation de cacheable, ele nem precisou acessar o ID de produto agora ele tem o dado cacheado ali, inclusive reusado para rota de get se eu voltar aqui na rota de post, ele realmente levou um pouco mais de tempo, mas se eu fizer agora um novo post, vamos ver se ele vai reduzir o tempo de criação e reduziu mesmo tenho 180 milissegundos e aqui eu tenho vou fazer um find trace de novo a rota de post agora não teve nenhuma interação com a API de produtos. Os dados estavam queixeados e a própria rota de post conseguiu se virar com os dados que ela tinha em memory. Vamos fazer uma validação agora da aplicação reinicializada, ou seja, sem os dados de cache. Vamos parar a aplicação aqui utilizando docker-compose vamos subir novamente e dessa vez passando forçando o cache a ser removido e a gente validar o consulta de fato da aplicação esperar terminar de subir a aplicação terminou de subir vamos acessar a rota aqui do vamos acessar o insomnia e consultar todas as orders por pela rota de get orders pelo insomnia então levou 2 pontos segundo 2.72 vale reforçar que a primeira consulta geralmente ela é mais demorada porque aplicação tá fazendo ali o arm up inicial é mas vamos olhar como que isso refletiu no nosso no Jager vamos Vamos consultar aqui, dar um refresh, abrir aqui, filtrar por service orders API, pegar aqui nos últimos cinco minutos find traces e vamos acessar a rota get orders aqui. Ele trouxe aqui, observe que agora ele trouxe, ele está fazendo cache, então ele entendeu que consultou a primeira vez o produto, levou 1.15 segundos, o produto 2 levou um pouco mais, um tempo menor, considerando que ele teve o armap ali da primeira consulta, mas considerando que ele vai consultando o mesmo produto várias vezes, aqui ele já não teve mais problema, ele já tava reusando o dado em então teve teve duas interações com a rota de produtos e depois não mais porque o dado tava em cash. Se eu fizer essa mesma consulta agora com esse mesmo essa mesma, o tempo vai ficar um pouquinho menor, se eu voltar aqui no Jager, trazer todos os dados, todas as traces, ele vai trazer aqui para gente e nessa vez ele identificou que não teve necessidade de interagir com a API de produtos. O último item que eu quero validar aqui é como que a aplicação se comporta ao incluir um produto que é inválido. Então, se na rota de post orders eu informar um produto inválido, por exemplo, vou só colocar no primeiro mesmo para forçar o erro e enviar. E aqui você percebe que o erro não está tratado. Ele retornou 500. Mas a pergunta que eu faço é, esse erro 500 é um erro não tratado na aplicação de orders, de solicitações ou na aplicação de produtos? Vamos descobrir. Imagina que você tem esse mesmo cenário no ambiente que que você possui várias aplicações rodando simultaneamente, né? Centenas, enfim, milhares de aplicações e você se depara com uma situação como essa. Vamos voltar no Yager, filtrando pelos últimos cinco minutos, e aqui eu já tenho com erro. Vamos clicar aqui e olhando aqui, ó, percebe que você tem um um símbolo de erro no aqui na frente do spam e o símbolo de erro se estende até a integração com a rota de produtos. Vamos clicar aqui no de produto e ver qual o erro que ele tá retornando. Ele retornou um product not found exception, até aí tudo bem, mas é um erro não tratado e ele retornou 500. Então, quem está retornando 500 é a API de produto. E por ela estar retornando 500, esse erro 500 vai se propagar por todas as aplicações, por todas as aplicações que dependem nesse serviço. Nesse caso, ele propagou esse erro quinhentos pra pra integração aqui de get da de produto. Aqui tem até o o erro aqui, a do erro. É tal, internal server error. Eu consigo olhar inclusive o que deu erro aqui nove nove nove nove e nove ah e aí ele claro propagou esse erro pra pra quem tá chamando a aplicação. Então, aqui tem uma oportunidade de ajustar, retornar um erro mais amigável, né? Um erro mais quando ele não encontrar um produto pelo ID informado. E não simplesmente retornar a RIO 500, porque aí nesse caso a tela, o canal, o aplicativo que estiver interagindo com essa aplicação, vai simplesmente dizer para o usuário final, uma mensagem amigável, porém que gera um pouco de desconforto, que é algo deu problema. E não é isso que você gostaria de dizer para o usuário final você gostaria de dizer, olha o produto que você informou não está disponível no catálogo não está mais disponível no catálogo, por favor entrar em contato, x aqui o serviço de tracing está nos revelando que tem uma oportunidade de tratamento de erro na aplicação de produto, e aí precisaria implementar lá, e aí precisaria implementar lá e aí garantir que a aplicação de orders consegue lidar agora com esse novo tipo de erro e propagar com a mensagem correta para o usuário final