Olá pessoal, tudo bem? Sejam todos muito bem-vindos a mais uma aula. E na aula de hoje, a gente ficou pendente de ajustar os adapters dos drivers. Porque aqui nos drivers, a gente está instanciando na mão os casos de uso e não é mais necessário. Porque agora a gente já está, já estamos com os casos de uso integrados ao framework. Então vamos lá. Estou aqui com o, vamos de controller e controller, e de resolver e resolver, tá? Então, vamos lá. Customer controller, a gente não precisa mais desse cara, agora a gente pode trazer o createCustomerUseCase. E também já aprendemos que a melhor injeção é aquela feita por construtor. Vamos também trazer o getCustomerById aqui. E aí a gente já gera um construtor com esses dois caras. Final, final. Eu falei pra vocês que eu estou viciado no final então na verdade é um é um vício bom não é um vício ruim tá é e aqui a gente não precisa mais dessa instanciação na mão a gente vai usar o create use case aqui e eu vou mover pra linha de baixo aqui a mesma coisa não precisamos mais de esse cara na mão a gente vai usar o get aqui então beleza primeiro já tá corrigido o que eu vou fazer ó eu vou copiar isso aqui e vou trazer aqui pro customer resolver só vou mudar o nome aqui e aqui a gente vai utilizar também aqui a get beleza então resolver também já tá corrigido no partner agora a gente vai precis partner, private final, get partner by id e criar os construtores final, final e aí esse cara aqui é objects.requiresNoNull beleza quebra uma linha aqui só para ficar um pouco mais legível aqui também a gente já corrige beleza vamos lá no partner resolver e já vamos trazer para cá e a diferença é que esse aqui é partner resolver e já vamos trazer pra cá ea diferença que isso aqui é parte resolver não precisamos mais desse cara aqui é o cliente não precisamos mais esse cara que é o get by id então dois já está corrigido agora tem um evento controller e o event resolver que ele não foi criado mas a gente aproveita para criar aqui agora. A gente já faz esse driver aqui. O EventController ele precisa do PrivateCreateEventUseCase. E a gente já sabe que é o Final e também vai precisar do Subscribe. final e também vai precisar do subscribe beleza vamos criar o controller com esses dois e o resto Aqui, objects.requires.null, objects.requires.null. Isso aqui, ó, vala. Aí aqui agora é create. E aí vamos só quebrar uma linha aqui. Beleza. Aqui também, ó, vala. É subscribe. E aí a gente pode quebrar uma linha aqui também, a gente já ganhou um pouquinho. Beleza, então já está feito, vamos rodar os testes? Gradle testes, vou rodar todos aqui. As adapters já estão tomando cara também, todos os testes passando, testes integrados, testes unitários, estamos seguros de que a nossa mudança está ok. Se a gente não tivesse esses testes, quero ver quem teria coragem de refatorar o projeto dessa maneira. Então, é super importante. Agora, vamos lá fazer o que eu falei, né? Vamos criar o resolver do event. Então, ele vai aqui no meio. Event, eu falo event, mora event, mora event, mas é event. Event. O event, vamos lá no event controller. Vamos ver o que ele recebe de parâmetros de entrada Que eu já nem lembro ID ID não, né? Porque a gente não usa ID É Date Name, Partner ID E Total Spots Beleza Na verdade, então é o seguinte Date Total Spots Que na verdade então é o seguinte ó, date, total spots, que na verdade é um int, e é obrigatório esses caras, melhor nem vou fazer validação aqui ainda, int, beleza, total spots, a name, spots a nem do nome do evento nome e ele tem uma integração como partner ele recebe o par o agido partner aqui ó partner dois pontos parcer só que como parte é um input é ele não vai deixar Então O que a gente pode fazer Vamos corrigir isso aqui já Vamos corrigir essa layer Não tem problema né A gente já corrige rapidinho O event DTO por exemplo Ele não é mais utilizado Vamos então mudar aqui só Para Se bem que vai quebrar outros testes Vamos vamos fazer o seguinte, por enquanto vamos fazer essa gambia aqui e depois a gente muda. Não, a gente já está mexendo nos drivers, nos adapters também, melhor corrigir isso agora já. O event.dto, que não diz absolutamente nada, a gente pode renomear ele. Vamos só ver onde está sendo usado ticket event controller event dto beleza então vamos mudar o nome desse cara para new event dto ele vai ser específico para criar um novo evento então ele vai ter o name, date e aqui é o long partner id isso aqui é tchau, isso aqui é tchau na verdade isso aqui pode ser um record class inclusive string name string date int total spots e long partner id nem precisa disso aqui a gente pode usar como record class partner id beleza essa validação agora a gente tem que usar mais porque a gente não precisa ir fundo para pegar o partner id, ir fundo em um objeto partner id total spots o do total spots aqui também está como int mas a gente pode deixar como int porque se mandarem nulo depois a gente valida lá internamente. Beleza. Vamos ver o que a gente quebrou aqui. Vamos rodar o teste. Ah, e antes a gente já pode também trabalhar aqui, ó. Date, total spots, name, e aí faltou o partner id que é do tipo id beleza a gente já tem o event, o event a gente pode mudar aqui também e aqui é obrigatório, obrigatório, obrigatório agora a gente já pode criar aqui também, vamos fazer o createEvent, event input e retorna um event e aí tem também o subscribe só que ele não tem ainda um input, vamos lá, vamos criar é um event id id e um customer id id show de bola subscribe input create partner então é subscribe customer to event input isso aqui e aí retorna um event Não lembro bem o que retorna, mas vamos deixar como event Beleza, já temos aqui As nossas mutations Vamos corrigir Ticket DTO Ticket DTO a gente usa pra alguma coisa Nem estamos usando mais, então vai pra vala Vamos corrigir Esse lado por inteiro agora Vamos rodar o teste pra ver O que está quebrando Event DTO, beleza vamos corrigir esse lado por inteiro agora vamos rodar o teste para ver o que está quebrando event.dto, beleza event.dto agora é um record class vamos ver os parâmetros name, date, total spots, partner id. Show de bola. Date, total spots, name, date, total spots name ah tá, aqui é o controller lá, né beleza aqui é a mesma coisa id new event dto ah tá beleza, é porque New Event DTO Ah, tá, beleza É porque tem o Event De resposta, né Então, o Event de resposta Não, na verdade, o que o Event Controller Tá retornando? Output Ah, é o próprio Output do Controller Do caso de uso Então Vamos fazer o seguinte, vamos utilizar ali aqui, Output, Create Customer Output, beleza. Vamos rodar os testes para ver se está passando, porque tem um problema com serialização e deserialização de Record Classes no Java, mas, bom, parece que tudo passou tranquilamente. Então, já corrigimos aqui o New event dto subscribe esse subscribe ele tá vindo como path e como tá esse cara a gente também pode fazer a mesma coisa que a gente fez ali ó long customerId que daí a gente já mata tudo isso, né? com um simples record class então, customerId beleza e aí vamos rodar aqui pra ver se tá ó aqui rodar todos os testes e reparem uma coisa que é interessante a gente está mudando a layer do adapter e quais os testes que estão quebrando os testes integrados de controller né os testes do caso de uso não quebrou não quebrou porque porque quebrou. Por quê? Porque o papel do adapter está sendo feito de maneira brilhante. Os DTOs de entrada não estão vazando para os casos de uso. Ou seja, eu consigo mudar a assinatura de uma entrada, a assinatura de uma REST API, sem prejudicar o caso de uso. Claro, os campos continuam sendo os mesmos Mas a forma como eu estou obtendo eles A classe A escrita do método Era uma classe, virou um record Esse tipo de coisa não está impactando no caso de uso Justamente por isso Porque não deveria impactar mesmo Então está funcionando perfeitamente beleza agora a gente pode na real criar a parte do do event resolver Vamos lá, ele é um controller e aí ele vai ter o primeiro que é o que retorna um event DTO, não, retorna um create event output, create event e aí ele é um mutation mapping E ele recebe como argumento Um New Event DTO Input E a gente injeta aqui Basicamente a mesma coisa Que está lá no event controller Opa A mesma coisa que está aqui No event controller E ele faz a mesma coisa que Quer dizer, a mesma coisa não Na verdade é o seguinte Vai retorná-lo Return Ident A diferença aqui é que agora é input E não é DTO input, input, input beleza, e aí a gente tem o outro mutation que é o do subscribe DTO só que esse cara não pode ser o subscribe DTO porque ele é diferente ele já recebe tudo no payload. Cadê? Subscribe Input. A gente não tem esse cara aqui. Então, vamos criar. Vamos criar dentro do GraphQL, tá? Package. DTOs. Subscribe Input DTO. Acho que subscribe input dto acho que subscribe input dto fica muito redundante vamos deixar só subscribe input ele recebe quem? customer id e long event id Vamos usar este cara aqui no resolver. Vamos trazer. Vamos ver qual é o nome do método lá em cima mesmo. Subscribe. E aí é subscribe.output. Subscribe. E aí aqui a gente vai passar o subscribe input. Que é basicamente dois caras, customer e o event. Beleza, vamos rodar os testes para ver se está funcionando. Criamos aqui o nosso resolver. criamos aqui o nosso resolver esse DTO na verdade ele está aqui só que eu acho que, não sei se faz muito sentido eu coloquei ele aqui, mas pensando bem agora vai ficar estranho ficar com dois DTOs um aqui para dentro e um aqui tudo bem que aqui é um DTO generalizado e eles são muito parecidos né eu acho que por questão de compliance acho que a gente pode colocar aqui também vamos fazer o seguinte vamos usar só esse, esse aqui vai pra vala e esse aqui, cadê? customer, não, event resolver, subscribe DTO, beleza. Aqui ele vai pegar daqui, só que aqui na REST API ele vai continuar pegando o event ID aqui da URL. Tá tudo bem, vamos rodar todos os testes. Opa, esse cara, DTO, ah tá, porque adicionei um parâmetro extra que vai ser como NULL, que é o Event ID. Vamos ver se agora passa tudo certinho. Perfeito, perfeito. Todos os testes estão passando certinho. Vamos rodar a aplicação para ver ela funcionando, bonito e bem feita. Vamos rodar a aplicação. Inicializou. Vamos lá no nosso partner. Está funcionando. Vamos dar um refresh aqui no GraphQL. Se a gente executar, continua funcionando. Vamos comentar esse aqui. E aí o que eu vou fazer? Vou copiar isso aqui pra baixo e vou mudar esse aqui. CreateEvent. Ele recebe, o que o CreateEvent recebe mesmo? aqui ó, mutation, create event, eventput, beleza, name, disney 2.0, mudar o restante Vamos pegar do próprio teste mesmo EventControllerTest Essa data TotalSpots TotalSpots Isso e O PartnerID É o 1 se eu não me engano Que a gente tinha criado Então vou colocar o 1 aqui Beleza E aí vamos executar opa opa opa the given id must not be null the given id must not be null partner id vamos ver aqui aonde que a gente role new ah, já achei esse cara vou rodar de novo, stop and rerun como a gente não tem teste de GraphQL aí fica difícil pegar. Por isso que é importantíssimo fazer teste de tudo. Depois eu posso ensinar vocês a fazer o teste integrado do GraphQL. Porque ficar fazendo esse teste na mão não dá. Esse teste regressivo, manual aqui, não dá. Mas criamos o evento de id 1 agora vou comentar esse cara vou colocar aqui embaixo vou descomentar e eu vou colocar o subscribe e a gente tem basicamente dois caras aqui que é o o customerid, vou colocar 1, e o eventid, que eu vou colocar 1 também. E aí eu não lembro o que eu retorno, vamos retornar o nome aqui. Tum, opa, orientado a erro, hein? Será que tem algum erro parecido? Vamos ver aqui, ó. Ah, tickets.lazyinitializationproxy exatamente faltou o que? faltou esse transactional que tem aqui a gente não colocou no resolver aí não vai né e aí já deixo uma dica né esse transactional a nível de controller ou a nível de adapter faz sentido? Depende, tem que tomar muito cuidado, porque se você colocar chamadas REST ali, é bom que você customize o seu pool de conexões corretamente, que também não vou entrar em detalhes aqui. A gente entrou bastante em detalhes nesse tipo baixo nível lá no curso Full Cycle, que é especial, especialista em java na parte do java é mas a customizar o seu pool de conexões mas não o pool em si a quantidade de conexões que a gente nem configurou a gente está aqui é indo no modo go horse mas lá no java vamos lá no admin do catálogo lá eu ensinei a vocês a como configurar exatamente o pool de conexões de cada propriedade que tem nele e o principal que ajuda muito nisso que é na verdade, é o, cadê? As properties do hybrid, que é o provider disables autocommit, fala como true, dou esse hint como true e deixo o próprio autocommit aqui falso porque a gente desabrita o autocommit e isso faz com que o HiMerence não fique que não precise pegar uma conexão assim que ele abre uma transactional então tem todo um detalhe por debaixo dos planos aqui que não vem ao caso em detalhe mas coloquei o transactionalional aqui então se a gente lançar the name was declared mas não foi retornado aqui a gente vai retornando outras coisas event id ticket status e reservation date então é subtype vamos criar o type aqui, aqui embaixo, type, subscribe, ele tem reservation date, que é do tipo string, ele tem ticket status, que é do tipo string e ele tem event id que é do tipo id, é obrigatório, obrigatório, obrigatório e esse é o retorno aqui, beleza agora vai. Se não apiar corretamente não dá né, aí quebra. Vou até dar um refresh aqui,ame aqui vai deixar de existir então posso e vento aí de e meio registro então ela tá vendo como é ruim você não ter teste preparada a gente está fazendo tudo regressivo dá muito trabalho né por isso que é importante a cobertura de teste mas vamos lá e 22 ao customer 2 um aí funcionou então é tá funcionando a gente tem que mais de quais aqui vamos ver a gente tem o customer of ae de nec acho que já testou inclusive Off ID, que eu acho que a gente já testou inclusive. Mas a gente tem... E acho que era isso, só isso que a gente tem de query. O resto já foi tudo testado, pessoal. Então é isso. Ajustamos algumas coisas. Aqui, Customer DTO. Vamos dar uma olhada aqui no Customer. Onde que a gente está usando? Na verdade, o Customer DTO a gente pode mudar para New Customer.dto, porque acho que no fim está sendo só usado para cá. E o New Customer.dto não tem ID. E ele também, vamos aproveitar para resolver isso, ele também pode ser um Record Class, String CPF, String Email, String Name. string cpf, string email, string name então isso aqui tudo vala, não precisamos mais, olha que delícia olha que delícia, cpf, email, name e o partner, já vamos fazer esse ajuste também, mesma coisa a gente não está precisando mais dele. New Partner DTO. O que a gente precisa? Record. String Name. String CNPJ. String Mail. E aí tudo isso aqui, ó, vá lá. Partner DTO. New Partner DTO. Aqui, ó, CNPJ. tudo isso aqui ó vala partner de ti ou nenhum par de 10 ou que o cnpj e mail nem me vou mudar os testes aqui testes que com certeza quebrou uma assinatura e-mail, name, cmpj, e-mail, name, cmpj, e-mail, name, vamos copiar isso aqui tem um monte de coisa para ajustar beleza name id aqui aqui não tem id então aqui é create partner.output.id vamos selecionar todos esses aqui mudar para cmpj então aqui é create partner.output.id vamos selecionar todos esses aqui, mudar para cmpj selecionar todos esses aqui, mudar para e-mail isso aqui, acho que pode ser isso aqui, não vai dar problema isso aqui pode ser isso aqui e aí depois a gente muda o partner para isso aqui acho que embaixo também precisa não precisa? não, é get por id isso aqui tá funcionando, aqui precisa jundol2 e beleza, deixa eu copiar então esse aqui de baixo que é um e-mail primário partner aqui, faltou? faltou lá embaixo new partner, calma aí, ah tá aqui é que o responso não está a gente está mapeando get partner baia de alt put beleza vamos dar todos os testes acho que quebrou o tema do também então é cpf e mail e cnp em cima subir lá em cima redundante beleza é colocar aqui e tira o var, né, porque já existe aqui a mesma coisa a gente vai agora usar esse tira o var e deixa eu copiar isso aqui, porque eu acho que a gente vai precisar aqui também e aqui é o get customer by id output ah não, isso aqui é o getCustomerById, output, ah não, isso aqui é o createCustomerUseCase.output, id, beleza, e esse aqui é esse aqui e id uff vamos rodar todos os testes você teria essa confiança em modificar tudo isso no seu projeto sim ou não? você é confiante de fazer essa mudança no seu projeto? se sim é porque ele está bem testado. Se não... Aí, meu camarada. Toma cuidado. Vamos ver aqui. Era para retornar um processable instance, mas não retornou. WIFI duplicated CPF. Ah, eu mudei o CPF em vez de mudar o e-mail. Beleza, vamos lá. Vamos de novo beleza, agora sim, tudo passou fizemos um bom refactor aqui nos nossos adapters de entrada, tanto do GraphQL quanto dos controllers agora a gente tem inclusive esse cara a gente até pode mudar. All Directors. Vamos mudar pra Rest. Assim como a gente deixou o GraphQL aqui, a gente deixa o Rest aqui. Porque faz mais sentido. E aí, o que a gente pode tirar aqui de observações, de conclusões? Esses DTOs, eles estão sendo usados tanto para GraphQL quanto para REST. Pode ser que no seu projeto faça sentido você ter uma camada de DTO para GraphQL e uma camada de DTO para REST, porque eles podem ser diferentes. O caso de uso é o mesmo, mas eles estão mudando por transporte, por layer de transporte diferente. Então, pode ser uma consideração de você fazer um para cada. No nosso caso, ele ia ficar muito redundante, porque a assinatura é a mesma para os dois cenários. Então, não faz sentido. É só o do subscribe aqui que a gente fez essa gambiagem, o image vem como nu, o outro vem presente, mas é uma coisa que você pode refletir para melhorar o seu projeto. Combinado? Bom, é isso. Espero que vocês tenham gostado. Ajustamos os adapters e ve