Luber – Luby Software https://luby.com.br Transformação Digital da concepção à entrega Fri, 04 Aug 2023 17:37:17 +0000 pt-BR hourly 1 NLP vs ChatGPT: descubra como aproveitar essas tecnologias em sua empresa https://luby.com.br/inovacao/nlp-vs-chatgpt/ Tue, 21 Feb 2023 13:32:45 +0000 https://luby.com.br/?p=17787 O Processamento Natural de Linguagem (NLP) é uma tecnologia que vem sendo utilizada há anos, mas que ganhou ainda mais destaque com a introdução do ChatGPT. Lançado em novembro de 2022, o ChatGPT se diferencia das outras opções de NLP por ser uma ferramenta de linguagem natural avançada que utiliza inteligência artificial para gerar respostas […]

O post NLP vs ChatGPT: descubra como aproveitar essas tecnologias em sua empresa apareceu primeiro em Luby Software.

]]>
O Processamento Natural de Linguagem (NLP) é uma tecnologia que vem sendo utilizada há anos, mas que ganhou ainda mais destaque com a introdução do ChatGPT. Lançado em novembro de 2022, o ChatGPT se diferencia das outras opções de NLP por ser uma ferramenta de linguagem natural avançada que utiliza inteligência artificial para gerar respostas precisas e coerentes em tempo real. Você sabe qual é a diferença de NLP vs ChatGPT?

Enquanto outras ferramentas de NLP se concentram principalmente na análise de texto, o ChatGPT é capaz de entender e responder a uma ampla variedade de perguntas e comandos de linguagem natural, tornando-o uma ferramenta valiosa para muitas empresas e organizações em diferentes setores.

NLP vs ChatGPT: qual é a diferença?

NLP vs ChatGPT (Transformers Generative Pretrained Language Model) são termos relacionados à inteligência artificial e processamento de linguagem natural, mas existe uma diferença clara entre eles.

Enquanto NLP é um ramo da inteligência artificial que se concentra em tornar as máquinas capazes de compreender e processar a linguagem humana, ChatGPT é uma aplicação específica desta tecnologia, que utiliza técnicas de NLP para fornecer respostas automatizadas a perguntas e conversas com os usuários.

O que é NLP?

A tecnologia do NLP inclui uma série de técnicas utilizadas para a análise, compreensão e geração de textos. É utilizado para melhorar processos, simplificar infraestruturas e reduzir custos empresariais. Alguns dos usos mais comuns do NLP incluem classificação de documentos, sumarização de documentos, criação de FAQ automatizadas, busca de documentos por similaridade e correção de texto.

E o ChatGPT?

O ChatGPT é um dos diversos modelos linguísticos desenvolvidos, que foram treinados especificamente para dialogar com humanos, o que o torna ideal para ser utilizado em chatbots.

Existem outras empresas no mercado que possuem modelos similares, e que encontram-se disponíveis em diferentes níveis de maturidade. Em um curto período de tempo, conseguimos alcançar resultados impressionantes, e com certeza a velocidade de lançamento de novos produtos e o aumento da concorrência só tendem a se intensificar ao longo dos próximos anos.

O ChatGPT consegue gerar conteúdos escritos impressionantes para um computador, e já é utilizado por muitas pessoas  para obter textos e ideias através de diálogos simples. 

Como utilizar NLP na sua empresa?

A utilização de NLP em sua empresa pode oferecer uma grande vantagem competitiva, permitindo a automação de tarefas que antes eram realizadas manualmente. No entanto, é importante considerar alguns pontos no planejamento de implantação de um serviço de NLP.

O primeiro ponto a ser considerado é a flexibilidade do sistema. Novas tecnologias estão surgindo e, com isso, é importante que a sua solução de NLP possua interfaces que permitam a troca de modelos sem a necessidade de reprogramação do sistema. Além disso, é importante levar em conta a eficiência e a precisão do modelo escolhido, bem como sua capacidade de aprendizado e atualização constante. Ao planejar o uso de NLP na sua empresa, é importante avaliar esses fatores para garantir uma implementação bem-sucedida e eficiente.

Quais serviços de NLP podem ser utilizados para melhorar sua operação?

Inúmeras aplicações podem ser desenvolvidas para melhorar seus processos, simplificar sua infraestrutura e reduzir custos com o NLP. Alguns dos casos de uso mais comuns são: 

  • Classificação de Documentos em categorias;
  • Sumarização de Documentos;
  • Criação de página de FAQ de forma automática;
  • Busca de documentos através da similaridade com outros artefatos;
  • Busca de documentos através de pesquisa semântica em seu repositório.
  • Correção de texto.

Dito isso, ao planejar a implantação de um projeto baseado em NLP, é importante levar em conta algumas questões cruciais:

  • Limpeza do texto, extraindo tags de HTML e caracteres especiais, por exemplo;
  • Particionamento do texto de acordo com o assunto, os capítulos, ou parágrafos;
  • Acesso automático ao conjunto de dados já existentes na empresa, incluindo arquivos de diferentes formatos (como .pdf,.docx e.txt);
  • Extração de texto de imagens de forma estruturada, como Notas Fiscais;/li>
  • Devolução do resultado de forma compreensível ao usuário final, seja através de sumários, filtragem ou outros;
  • Segurança dos dados, evitando a injeção de dados através de interface do usuário;
  • Hospedagem dos modelos em nuvem própria da empresa, dependendo da sensitividade dos documentos.

Potencialize sua operação com NLP

NLP é uma tecnologia que tem ganhado cada vez mais espaço no mercado, trazendo consigo uma infinidade de possibilidades de automatização e melhoria de processos. Desde a classificação de documentos, passando pela busca semântica e correção de texto, a NLP se apresenta como uma ferramenta essencial para quem busca evoluir e se destacar no mercado.

O ChatGPT, por sua vez, é um modelo de NLP desenvolvido pela OpenAI, que tem se destacado pela sua capacidade de conversação natural e capacidade de responder a perguntas complexas com precisão. A combinação da tecnologia NLP com o ChatGPT é um passo importante para a evolução da interação humana com máquinas e traz consigo a possibilidade de criação de chatbots, sistemas de atendimento ao cliente e muito mais.

Com mais de 20 anos de experiência, a Luby é a parceira ideal para o sucesso de seu projeto de NLP. Com uma equipe altamente qualificada e soluções inovadoras, a Luby poderá ajudá-lo a aproveitar todos os benefícios da tecnologia NLP. Seja para automatizar os processos internos, melhorar a experiência do usuário ou até mesmo desenvolver soluções personalizadas para a sua empresa, a Luby está pronta para garantir o máximo de eficiência e segurança.

Não perca mais tempo e invista em inteligência artificial com a Luby. Clique aqui e saiba mais!

Rubens Mau, Data Scientist.

O post NLP vs ChatGPT: descubra como aproveitar essas tecnologias em sua empresa apareceu primeiro em Luby Software.

]]>
Gerenciador de Pacotes: entendendo npm, npx e yarn no Node Package Managers https://luby.com.br/desenvolvimento/software/tutoriais/gerenciador-de-pacotes/ Thu, 10 Nov 2022 15:09:35 +0000 https://luby.com.br/?p=13746 No cenário de desenvolvimento utilizando JavaScript/TypeScript, é impensável a construção de aplicações profissionais sem a utilização de um gerenciador de pacotes. Tanto é que, ao instalar o runtime (ambiente de tempo de execução) de javascript Node.js em sua máquina, já consta a opção (marcada por padrão) de instalar também o seu gerenciador de pacotes padrão: […]

O post Gerenciador de Pacotes: entendendo npm, npx e yarn no Node Package Managers apareceu primeiro em Luby Software.

]]>
No cenário de desenvolvimento utilizando JavaScript/TypeScript, é impensável a construção de aplicações profissionais sem a utilização de um gerenciador de pacotes. Tanto é que, ao instalar o runtime (ambiente de tempo de execução) de javascript Node.js em sua máquina, já consta a opção (marcada por padrão) de instalar também o seu gerenciador de pacotes padrão: npm.

A partir do npm, podemos instalar pacotes que muitas vezes formam a base para o desenvolvimento de aplicações complexas, além de embutir no projeto um sistema de gerenciamento desses pacotes e suas dependências.

Neste artigo, vamos explicar as funcionalidades e histórico dos gerenciadores mais populares e suas diferenças. Para melhor compreensão, iremos abordar os termos em inglês, que é a forma mais utilizada no dia a dia do desenvolvimento.

Por que é preciso ter um gerenciador de pacotes?

Como pessoas desenvolvedoras, faz parte da nossa responsabilidade prezar pela otimização de tempo e recursos em nossos projetos. Em uma analogia popular, imaginemos que o nosso trabalho fosse montar carros: não seria eficiente realizarmos da extração do petróleo até a produção final dos pneus, sendo que podemos pegá-los prontos e reutilizar em todos os carros que produzirmos.

Todavia, é sim necessário mantermos o registro de quais componentes foram utilizados e suas versões, para garantir que todas pessoas trabalhando no carro utilizem os mesmos componentes. Com projetos de desenvolvimento, a situação é similar: seria ineficiente que todo projeto desenvolvesse do zero uma aplicação que expõe um servidor para a web, considerando que a mesma atividade já foi realizada milhares de vezes.

Aí entra a necessidade de um gerenciador de pacotes: além de nos apontar para um repositório de recursos, ele também garante que todas pessoas envolvidas no desenvolvimento do projeto sigam a mesma árvore de dependências dele. Ainda, ao utilizar um gerenciador de pacotes, facilita-se em muito a atualização das versões dessas dependências. Ao invés de ter que atualizar o pacote e toda sua lista de dependências (e dependências dessas dependências sucessivamente). Tudo isso é solucionado com um comando simples como npm update nomeDoPacote.

Apesar de utilizar um nome que representa sua própria função, o npm não é o único gerenciador de pacotes do node. Como veremos adiante, empresas também desenvolveram suas próprias soluções, como é o caso do yarn.

As três partes do npm

O npm consiste em partes distintas: o site (https://www.npmjs.com/) e o registro e a Command Line Interface (CLI – Interface de linha de comandos). O site é utilizado para descobrir pacotes, configurar perfis e gerenciar outros aspectos da experiência com npm. A CLI é executada a partir de um terminal e é como a maioria das pessoas desenvolvedoras interagem com o npm. Por fim, o registro é um grande banco de dados público de software JavaScript e as meta-informações que o cercam.

Site npm

O site npm é o local onde é possível realizar o registro de uma conta para publicação de pacotes. Através dele, também é possível consultar os pacotes no registro, além de outras funções de gerenciamento (fazer parte de uma organização e administrar pacotes privados).

Registro npm

O registro npm público é o banco de dados que contém as informações sobre os pacotes publicados, cada um composto por código e metadados. Desenvolvedores de código aberto e desenvolvedores de empresas utilizam o registro npm para contribuir com pacotes para toda a comunidade ou membros de suas organizações e fazer download de pacotes para usar em seus próprios projetos.

Por ser um registro público, outros gerenciadores de pacotes (como o yarn, que explicaremos mais adiante) utilizam o mesmo registro do npm.

CLI npm

Ao utilizar a CLI do npm, é possível instalar pacotes que estejam em seu registro utilizando seu nome e, opcionalmente, a versão desejada. Os pacotes podem ser baixados de forma global (para serem utilizados a qualquer momento, independente do escopo) ou local (para serem vinculados e utilizados especificamente em um projeto). Um guia de uso da CLI exigiria um artigo focado nisso, porém os comandos mais usuais são de instalação e remoção de pacotes, respectivamente: npm install nomeDoP.

npm install nomeDoPacote
npm uninstall nomeDoPacote

Podemos utilizar a flag -g para definir a instalação global do pacote, normalmente utilizada para pacotes voltados para o desenvolvimento em si, com scripts executáveis pelo comando npx.

Ao executar o comando install no escopo de um projeto, os arquivos do pacote e suas dependências são baixados para uma pasta chamada node_modules e organizados através de dois arquivos na raiz do projeto: package.json e package-lock.json. Como sempre, a melhor fonte para saber mais sobre comandos da CLI é a documentação oficial: https://docs.npmjs.com/.

Arquivos package

A organização dos pacotes instalados pelo npm se dá através de dois arquivos no formato JSON: package e package-lock. A seguir, explicaremos a função dos dois.

package.json

Ao instalar pacotes com o comando npm install xxx ou ao iniciar um projeto com npm init, é criado ou modificado um arquivo chamado package.json. Esse arquivo possui as informações básicas para que todas pessoas consigam ver as informações básicas sobre aquele projeto, scripts disponíveis e a rede de dependências, tanto de produção quanto de desenvolvimento.

Caso você apenas instale um pacote em um projeto não inicializado pelo comando npm init, a única chave será dependencies com o valor da propriedade instalada. Exemplo realizando a instalação do Express:

{
"dependencies": {
"express": "^4.18.2"
}
}

Um arquivo package.json naturalmente cresce em conjunto com a complexidade do projeto, de forma automática. Para ver a lista de propriedades disponíveis no arquivo, recomendo a leitura da documentação, especialmente sobre a propriedade scripts que pode definir diversos comandos como execução de testes ou abertura de servidor para desenvolvimento.

package-lock.json

O arquivo package-lock.json é criado e atualizado de forma automática por qualquer operação do npm que modifique os conteúdos da pasta node_modules ou o arquivo package.json. Ele descreve a árvore de arquivos exata que foi gerada, de modo que as instalações subsequentes possam gerar árvores idênticas, independentemente das atualizações de dependência intermediárias.

Ao contrário do package.json, não devemos atualizar esse arquivo manualmente, pois ele serve exatamente para que o npm possa gerar operações idênticas independente do contexto em que esteja sendo rodado. Mais adiante veremos uma alternativa ao npm chamada yarn. Essa alternativa produz um arquivo similar chamado yarn.lock, que possui a mesma função do package-lock.json, mas descreve as instalações realizadas pelo yarn.

Comando npx

Acima, comentamos sobre como podemos usar o comando npx para executar scripts de pacotes instalados com npm. A utilização é simples (entre colchetes são parâmetros opcionais):

npx nomeDoPacote [@] [args...]

Este comando permite que você execute um comando arbitrário de um pacote npm (um instalado localmente ou obtido remotamente – se algum pacote solicitado não estiver presente nas dependências do projeto local ou na máquina de forma global, ele será instalado em uma pasta no cache do npm). Um dos scripts de pacote mais utilizados, principalmente para pessoas desenvolvedoras FrontEnd, é o create-react-app:

npx create-react-app nome-do-meu-app

A execução desse script cria toda estrutura básica de um projeto utilizando React, acelerando consideravelmente o setup do projeto. Dada a natureza do comando, tanto é possível integrar um executável em um pacote com mais ferramentas ou criar pacotes cuja única função é sua execução. Como inspiração, recomendo digitar o comando npx azhariel no terminal para um exemplo de cartão de visitas simples e disponível globalmente para usuários do npm.

Yarn

Apesar de todos os méritos do npm, algumas pessoas desenvolvedoras viram a necessidade de melhorias no gerenciador de pacotes. Uma dessas pessoas foi Sebastian McKenzie, que resolveu iniciar a implementação do gerenciador yarn (em português, literalmente “novelo [de lã]”, mas é uma sigla para “Yet Another Resource Negotiator”; em português, “Mais um negociador de recursos”) enquanto trabalhava no Facebook. Apesar dessa conexão inicial com a gigante tech, o gerenciador é open source e não é mantido diretamente por nenhuma empresa.

Para utilizar o yarn, devemos instalá-lo globalmente utilizando o próprio npm:

npm install --global yarn

Atualmente, o yarn utiliza o mesmo registro mantido pelo npm, apontando apenas para um domínio de CNAME diferente. Sendo assim, as principais diferenças com o gerenciador padrão se dão na arquitetura, estratégia e performance dos gerenciadores.

Comandos

Existem algumas diferenças nos comandos dos dois gerenciadores. Como sempre, sugiro sempre a consulta na documentação oficial de ambos, mas em resumo podemos utilizar a seguinte tabela:

node package luby

 

Instalação dos Pacotes

Enquanto o npm instala os pacotes designados diretamente na pasta node_modules, o yarn, por padrão, realiza a instalação a partir de uma pasta cache que é utilizada globalmente na máquina. Apesar de também manter uma pasta cache, o npm busca os arquivos no registro para o projeto. Essa estratégia de cache permite ao yarn, a instalação de dependências de forma offline, contanto que já estejam disponíveis no cache local.

Ainda sobre a instalação de pacotes, o yarn opta por uma estratégia de download e instalação em paralelo, otimizando o tempo total necessário para instalação de diversas dependências. Em contrapartida, o npm realiza o download
e instalação de forma linear, um pacote por vez.

Estratégia Plug N Play (PNP)

Desde 2018, o yarn possibilita a utilização de uma estratégia otimizada para auxiliar o Node a encontrar a localização dos pacotes instalados. Normalmente, o Node procura por módulos instalados de forma recursiva: quando há o requerimento de uma dependência, o runtime procura pela mesma na pasta node_modules de onde houve a requisição. Caso não seja encontrada, ele volta a procurar na pasta node_modules um nível acima, sucessivamente, até encontrar o local de instalação da dependência (ou não encontrá-la e gerar um erro de dependência).

Como alternativa a essa sequência de busca, o yarn gera um único arquivo .pnp.cjs em vez da pasta node_modules. O arquivo .pnp.cjs contém vários mapas: um vinculando nomes e versões de pacotes à sua localização no disco e outro vinculando nomes e versões de pacotes à sua lista de dependências. Com essas tabelas de pesquisa, o yarn pode informar instantaneamente ao Node onde encontrar qualquer pacote que ele precise acessar, desde que faça parte da árvore de dependências.

Ela é utilizada por padrão na versão mais recente do yarn (2, apelidado de berry). Mais informações sobre podem ser encontradas na documentação oficial.

Segurança

Ambos gerenciadores possuem funções que garantem a segurança na instalação e execução dos pacotes. Porém, utilizam estratégias diferentes. Ao requisitar a instalação de um pacote, o yarn garante a integridade dos dados gerando um checksum, que é integrado aos dados e comparado localmente, rejeitando os dados caso os cálculos apresentem resultados diferentes. Por outro lado, o npm utiliza um algoritmo SHA-512 para verificar a integridade dos pacotes, comparando com a hash disposta no arquivo package-lock.json.

Além disso, o npm também conta com o comando npm audit, que informa sobre possíveis vulnerabilidades nas versões das dependências instaladas e o comando npm audit fix, que visa resolver as vulnerabilidades reportadas com upgrade para versões mais recentes.

Velocidade

Como existem diversos fatores que podem influenciar na velocidade final de uma operação dos gerenciadores de pacote, é necessária a análise de diversos cenários. Pensando nisso, um outro gerenciador de pacotes chamado pnpm realiza benchmarks diários entre npm, yarn e o próprio pnpm. Os resultados podem ser conferidos no site do próprio pnpm. Como exemplo, esses são os resultados obtidos na data de publicação deste artigo:

Gerenciador de Pacotes: entendendo npm, npx e yarn no Node Package Managers Luby Software

Na maioria dos cenários, o yarn aparece com vantagem sobre as operações do npm, em especial quando utiliza a estratégia PnP em conjunto com cache e lockfile, gerando uma instalação quase instantânea dos pacotes.

Conclusão

Apesar de diferenças pontuais, ao fim do dia, mais importante do que a escolha de gerenciador de pacotes é a escolha dos pacotes em si.

Quando optamos por utilizar um pacote, embarcamos também em todas as dependências relacionadas àquele pacote, o que pode gerar um efeito cascata desnecessário para o andamento do projeto.

Dito isso, a construção de aplicações modernas e profissionais quase que necessariamente exige a instalação de pacotes e, com isso, a compreensão básica sobre o gerenciamento desses pacotes é uma habilidade necessária para a pessoa desenvolvedora.

Veja também:

Como criar Micro Interações em ReactJS?

Veja mais tutoriais!

Autor: Renan Zambon Braga.

O post Gerenciador de Pacotes: entendendo npm, npx e yarn no Node Package Managers apareceu primeiro em Luby Software.

]]>
O que é Injeção e Inversão de dependências? https://luby.com.br/desenvolvimento/software/conceitos/injecao-e-inversao-de-dependencias/ Mon, 31 Oct 2022 19:40:28 +0000 https://luby.com.br/?p=12780 No mundo da programação, existe uma relação entre os termos injeção e inversão de dependências. Porém, geralmente são mal utilizados no decorrer de um projeto ou pouco conhecidos no desenvolvimento de sistemas digitais. Neste artigo, iremos apresentar uma breve introdução do que é cada um desses termos e de como utilizá-los corretamente. Mas, para entendê-los, […]

O post O que é Injeção e Inversão de dependências? apareceu primeiro em Luby Software.

]]>
No mundo da programação, existe uma relação entre os termos injeção e inversão de dependências. Porém, geralmente são mal utilizados no decorrer de um projeto ou pouco conhecidos no desenvolvimento de sistemas digitais.

Neste artigo, iremos apresentar uma breve introdução do que é cada um desses termos e de como utilizá-los corretamente. Mas, para entendê-los, primeiramente devemos compreender o significado de dependências.

O que são dependências?

Quando estamos programando, podemos criar classes para as mais diversas finalidades e funcionalidades. Então, se você instancia um objeto dentro de outra classe, isso automaticamente a torna uma dependência dessa classe. É nítido que não fazemos esse tipo de coisa apenas uma vez durante o projeto. Isso é feito em diversos momentos. Por isso, gera código com forte acoplamento ou baixa coesão segundo os princípios do SOLID.

Codar dessa maneira é um processo quase que natural utilizado pela maioria dos desenvolvedores que ainda estão aprendendo ou desconhecem alguns princípios e consequências que um código fortemente acoplado pode gerar no futuro.

Veja que, no exemplo abaixo, queremos conectar o CreateUserController, para que ele possa criar um User a partir de um repositório CreateUserRepository ao realizar alguma solitação HTTP do tipo POST a determinada rota.

Injeção e Inversão de Dependências 1

Perceba que, utilizando essa abordagem, uma classe começa a depender de uma outra para que a primeira funcione. E isso deve ser evitado desacoplando o uso de um objeto da sua criação, deixando as classes independentes.

Qual o problema gerado por essa abordagem?

Sempre que criamos uma instância de CreateUserController, uma outra instância (com a implementação direta da criação do usuário no banco) de CreateUserRepository deve estar disponível para que haja compilação do nosso código.

Dito isso, podemos pensar que o sentido das dependências segue de tal forma:

  • CreateUserController depende diretamente de CreateUserRepository

Injeção e Inversão de Dependências 2

Injeção de dependência

Podemos dizer que injeção de dependência é basicamente passar via construtor as dependências (já instanciadas fora da classe) que seu componente irá utilizar. Chamamos esse tipo de injeção de Constructor Injection.

Perceba abaixo que melhoramos o nosso código injetando uma instância de CreateUserRepository no construtor de CreateUserController, ao invés de instanciarmos esse repositório diretamente de dentro do nosso controller.

Injeção e Inversão de Dependências 3

Mas isso ainda não é o suficiente!

O CreateUserController ainda depende de CreateUserRepository.

Injeção e Inversão de Dependências 4

Antes de mostrar a solução derradeira para essa situação e ainda falando um pouco sobre a desvantagem que é utilizar esse tipo de abordagem, não poderíamos, por exemplo, ‘mockar’ valores a partir de testes unitários utilizando a classe CreateUserRepository (que faz uma implementação e operações diretamente com um banco de dados SQL) para um banco de dados simulado em memória com o intuito de criar ou utilizar testes unitários. Isso porque nossos testes deixariam de ser unitários, uma vez que estamos dependendo de uma implementação que utiliza a persistência nos dados.

Ou seja, já que amarramos nosso CreateUserController, ele então depende exclusivamente da implementação contida em CreateUserRepository.

Dito isso, o que buscamos de fato? Precisamos inverter as direções! Ao invés de dependermos de implementações, devemos depender de contratos ou interfaces.

Inversão de dependência

O Dependency Inversion Principle é um princípio do SOLID que afirma: dependa de abstrações e não de implementações.

Segundo Uncle Bob, esse princípio pode ser definido assim:

  1. Módulos de alto nível não devem depender de módulos de baixo nível. Ambos devem depender da
    abstração.
  2. Abstrações não devem depender de detalhes. Detalhes devem depender de abstrações.

Então, a inversão de dependência é uma prática que nos permite desacoplar componentes. Agora, veja como se comporta a direção e o fluxo de dependências:

Injeção e Inversão de Dependências 5

 

Neste ponto, nosso CreateUserController aponta para uma interface que abstraímos a criação de um usuário, ao invés da classe concreta CreateUserRepository. Isto é, inserindo uma interface ICreateUserRepository entre os dois componentes: CreateUserController eCreateUserRepository. Dessa forma, iremos ver a seguir como isso se reflete no código:

Injeção e Inversão de Dependências 6

Assim, no CreateUserController, iremos consultar a interface ICreateUserRepository ao invés da classe CreateUserRepository.

Injeção e Inversão de Dependências 7

Dessa forma, acabamos de inverter as dependências.

Qual a real vantagem da Injeção e Inversão de dependências?

Anteriormente, falamos que não seria possível criar nossos testes unitários ‘mockados’ passando um CreateUserRepository em um CreateUserController. Isso porque os testes ficariam lentos e precisaríamos de uma conexão com o banco de dados para executar esse test.

Entretanto, utilizando inversão de dependências podemos escrever uma classe qualquer MockCreateUserRepository, que implementa a interface ICreateUserRepository, e cria em memória um atributo que seja um array de Users para simularmos um banco de dados. Com isso, será possível executarmos testes mais rápidos e de forma íntegra, de acordo com nosso negócio.

Injeção e Inversão de Dependências 8

Conclusão

Passando uma instância dessa classe MockCreateUserRepository para o nosso CreateUserController, você pode escrever um teste unitário utilizando jest sem preocupações com operações reais em um banco de dados.

Lido até aqui, agora você pode ter uma ideia primária de como colocar em prática os princípios da inversão e injeção de dependências em suas classes, utilizando de interfaces como principal aliado. Se tiver em dúvida, lembre-se sempre: dependa de abstrações, e não de implementações.

Veja também:

Introdução ao React JS

Autor: Clidenor Issac de Almeida Cabral.

O post O que é Injeção e Inversão de dependências? apareceu primeiro em Luby Software.

]]>
Como criar uma API REST e validar dados com Fastify, Zod e Typescript https://luby.com.br/desenvolvimento/software/programacao/api/como-criar-uma-api-rest/ Tue, 11 Oct 2022 19:24:31 +0000 https://luby.com.br/?p=12303 Durante o processo de aprendizado, é comum que o desenvolvedor back-end seja introduzido apenas ao Express, mas será que essa é a única opção? Neste artigo, iremos ver alternativas para o desenvolvimento de API’s, como criar uma API REST e como podemos aumentar a produtividade e a segurança do código com Typescript e validações do […]

O post Como criar uma API REST e validar dados com Fastify, Zod e Typescript apareceu primeiro em Luby Software.

]]>
Durante o processo de aprendizado, é comum que o desenvolvedor back-end seja introduzido apenas ao Express, mas será que essa é a única opção? Neste artigo, iremos ver alternativas para o desenvolvimento de API’s, como criar uma API REST e como podemos aumentar a produtividade e a segurança do código com Typescript e validações do Zod.

O que é uma API REST?

Simplificadamente, uma API REST é uma forma de pedir algo para um servidor por meio de um protocolo de comunicação (HTTP), executando uma função no servidor e retornando uma informação. Durante todo esse processo, podem ocorrer diversas validações e transformações para garantir que o que foi pedido seja retornado corretamente.

Por que utilizar Typescript?

O Typescript permite que você escreva o código Javascript com mais segurança, menos erros e mais facilidade de manutenção. Além disso, ele permite que você utilize o “auto complete” da sua ferramenta de programação, como o VS Code, para te ajudar a escrever o código.

Somado a isso, tanto o Fastify quanto o Zod possuem suporte a Typescript, o que facilita ainda mais o desenvolvimento.

Por que utilizar Fastify?

O Fastify é um framework que permite que você crie servidores REST, bem como uma API REST. Em comparação com o Express, a forma como se desenvolve uma API é bem parecida. Entretanto, ele é mais performático, moderno e de fácil aprendizado, contando com várias outras vantagens. Por exemplo, um ecossistema de plugins que são mantidos tanto pela comunidade quanto pela própria equipe do Fastify.

Além de ter vantagens mais avançadas, como Decorators, Encapsulation, Lifecycle, Serialization, Hooks, entre outros.

Por que utilizar Zod?

O Zod é uma biblioteca que permite que você defina regras para validar dados, gerando automaticamente os tipos para o Typescript. Utilizaremos ele para validar os dados que serão enviados para o servidor REST. Caso os dados não correspondam às regras definidas, o servidor irá retornar um erro apontando qual campo está incorreto e o que era
esperado.

Além disso, o Zod gerará automaticamente os tipos do Typescript para você, permitindo a utilização dos dados recebidos de forma mais segura.

Passo a passo para criar uma API REST com Fastify e Zod

Para este tutorial de criação de uma API REST, foram utilizadas as seguintes ferramentas:

  • Node.js (v18.10.0);
  • VS Code;
  • Insomnia.

Instalando as dependências

Primeiro, vamos criar uma pasta chamada fastify_zod e abrir o terminal nela. Em seguida, vamos instalar as dependências necessárias para o projeto com os seguintes comandos:

1. npm init -y
2. npm i fastify zod
3. npm i -D typescript @types/node tsx

Importando as dependências

Após o primeiro passo, vamos criar um arquivo chamado server.ts e importar as dependências que instalamos anteriormente:

import Fastify from "fastify"
import { z } from "zod"

Instanciando o Fastify e criando as regras de validação do objeto User

Iremos instanciar o Fastify em uma constante chamada server e criar as regras de validação do objeto User com o Zod.

Para isso, vamos criar uma constante chamada userSchema e definir as regras de validação do objeto User. Neste caso, este é um objeto com os campos name, email e password. Para cada campo, iremos definir o tipo, o tamanho
mínimo e máximo de caracteres e o formato do campo (email).

const server = Fastify()

const userSchema = z.object({
name: z.string().min(3).max(50),
email: z.string().email(),
password: z.string().min(8).max(50)
})

Simulando um banco de dados

Para simular um banco de dados, iremos criar uma constante chamada users que será um array de objetos do tipo User. Podemos aproveitar a tipagem feita pelo Zod para inferir o tipo do objeto User da seguinte forma:

type User = z.infer <typeof userSchema>
const users: User[] = []

Criando a rota de criação de usuário

Agora, vamos criar a rota de criação de usuário. Para isso, vamos utilizar o método post do Fastify e passar como primeiro parâmetro a rota que será acessada e como segundo parâmetro uma função que irá receber como parâmetro o objeto request e reply.

Dentro dessa função, iremos pegar os dados enviados pelo usuário e validar se eles estão de acordo com as regras definidas anteriormente. Caso estejam, iremos adicionar o usuário no array de usuários e retornar o usuário criado.

Caso não estejam, iremos verificar se o erro é do tipo ZodError e retornar o erro para o usuário (lembrando sempre de retornar o Status Code correto).

server.post("/users", (request, reply) => {
try {
const user = userSchema.parse(request.body)
users.push(user)
return user
} catch (error) {
const errorJson = JSON.stringify(error)
if (error instanceof z.ZodError) return
reply.status(400).send(errorJson)
else return reply.status(500).send(errorJson)
}
})

Criando a rota de listagem de usuários

Semelhante ao passo anterior, criaremos a rota de listagem de usuários utilizando o método get e retornaremos o array de usuários.

server.get("/users", () => users)

Configurando a inicialização do servidor

Por fim, vamos iniciar o servidor utilizando o método listen do Fastify e passando como parâmetro um objeto com a porta que o servidor irá funcionar e uma função anônima que será executada quando o servidor estiver pronto para receber requisições.

server.listen({ port: 3000 }, (err, address) => {
if (err) {
console.error(err)
process.exit(1)
}
console.log(`Server listening at ${address}`)
})

Inicializando o servidor

Após verificar que o código está correto, basta executar o comando npx tsx ./server.ts no terminal para executar o código. O servidor irá iniciar na porta 3000 e enviará uma mensagem no terminal informando que está pronto para receber requisições.

Inicializando o servidor - como criar uma API REST

 

Testando a API

Para testar a API, vamos utilizar o Insomnia (ou qualquer outra ferramenta de sua preferência). Primeiro, vamos criar um novo usuário com uma requisição do tipo POST para a rota http://localhost:3000/users e passar como corpo da requisição um objeto JSON com os campos name, email e password.

Ao enviar a requisição, o corpo da resposta será o objeto JSON do usuário criado e o Status Code será 200.

Testando a API - como criar uma API REST

Caso tentemos criar um usuário com um campo inválido, como o email, o corpo da resposta será o erro retornado pelo Zod e o Status Code será 400.

Como criar uma API REST e validar dados com Fastify, Zod e Typescript Luby Software

Para listar os usuários, basta enviar uma requisição do tipo GET para a rota http://localhost:3000/users. Dessa forma, o corpo da resposta será um array com todos os usuários criados e o Status Code será 200.

Testando a API 3 - como criar uma API REST

Conclusão

Neste artigo, vimos como utilizar o Fastify para criar uma API REST e utilizar o Zod para validar os dados enviados pelo usuário. Pensando em melhor ainda mais sua experiência na criação de uma API REST, confira as referências de documentação utilizadas neste artigo:

Autor: João Carlos Magalhães de Castro.

O post Como criar uma API REST e validar dados com Fastify, Zod e Typescript apareceu primeiro em Luby Software.

]]>
Como criar snippets no VSCode para agilizar o desenvolvimento em React https://luby.com.br/desenvolvimento/software/criar-snippets-no-vscode/ Tue, 04 Oct 2022 11:01:28 +0000 https://luby.com.br/?p=12272 Quem costuma desenvolver aplicações em React provavelmente já se deparou escrevendo diversas vezes o mesmo bloco de código. Se estiver criando um componente funcional, por exemplo, você terá que criar uma função cujo nome inicia com letra maiúscula, que retorna XML (aquele JavaScript que parece HTML) e exportá-la. Neste artigo, vamos explorar um tutorial para […]

O post Como criar snippets no VSCode para agilizar o desenvolvimento em React apareceu primeiro em Luby Software.

]]>
Quem costuma desenvolver aplicações em React provavelmente já se deparou escrevendo diversas vezes o mesmo bloco de código. Se estiver criando um componente funcional, por exemplo, você terá que criar uma função cujo nome inicia com letra maiúscula, que retorna XML (aquele JavaScript que parece HTML) e exportá-la. Neste artigo, vamos explorar um tutorial para você aprender a criar snippets no VSCode.

Para estilizar utilizando uma biblioteca como Styled Components, é necessário criar um componente retornado pela função styled e também exportá-lo. Embora pareça pouca coisa, essa etapa será necessária em absolutamente todo o componente que será criado, o que é quase certo que serão muitos. E estamos falando aqui apenas em criar as condições necessária para iniciar o projeto!

Felizmente, há uma solução muito simples de ser implementada e que causa um grande impacto na produtividade: os snippets, que são blocos de códigos pré-configurados e facilmente acessíveis. O VSCode possui muitas extensões de snippets excelentes que podem ser encontradas sem dificuldade pesquisando “[nome da tecnologia] snippets”.

No entanto, muitas vezes faz mais sentido criar seus próprios snippets, utilizando o seu padrão de escrita ou o padrão estabelecido pelo seu time.

Nesse artigo, vamos aprender o básico sobre como criar snippets no VSCode e aplicar esses conhecimentos na criação de códigos muito familiares para os desenvolvedores de React: a criação de um componente funcional e estilização utilizando o Styled Components.

Passos iniciais para criar snippets no VSCode

Vamos criar nosso primeiro snippet:

  1. No VSCode, digite o atalho Ctrl + Shift + P para ter acesso às opções;
  2. Selecione “Snippets: Configure User Snippets”;
  3. Selecione “New Global Snippets File…” (como ele deverá estar disponível para todos os projetos que faremos, deverá ser um arquivo global). Se o snippet em questão deverá ser disponibilizado para apenas uma linguagem, ele poderá ser criado no arquivo específico ao invés do arquivo global;
  4. Escolha um nome para o seu arquivo de snippets. Uma sugestão é separar seus arquivos por tecnologia. Como estamos criando snippets de React, esse será o nome do nosso arquivo.
![[criar snippet.gif]]

Estrutura de configuração do snippet

Assim, criamos um arquivo JSON contendo as instruções de como criar um snippet comentadas e um exemplo simples. Vamos destrinchar a estrutura desse exemplo que o VSCode nos forneceu.

"Print to console": {
"scope": "javascript,typescript",
"prefix": "log",
"body": [
"console.log('$1');",
"$2"
],
"description": "Log output to console"
}

O primeiro passo é definir o nome do snippet, no caso, “Print to console”. Dentro desse objeto, vamos definir:

  • “scope” – serão as extensões de arquivo que terão acesso ao snippet (observe a formatação: uma única string com as extensões separadas por vírgula)
  • “prefix” – apelido para o VSCode entender que queremos utilizá-lo
  • “body” – onde estará contido o código que queremos reutilizar (mais adiante vamos detalhar como formatar o código dentro desse body)
  • “description” – detalhará o que o código faz.

Para utilizar esse snippet de exemplo, vamos criar um arquivo com extensão “ts” (perceba que o TypeScript está definido no scope) e digitar o prefix para verificar se ele será reconhecido.

![[2022-09-16 (2).png]]

De fato, ao digitar “log”, a sugestão do nosso snippet é exibida e o nome que foi definido é mostrado no canto direito.

Formatação do código no body do JSON

Você deve ter notado que o “body” (espaço onde armazenamos o código que queremos reaproveitar) tem uma estrutura de array de strings. Portanto, não podemos simplesmente copiar um código escrito em JavaScript e inseri-lo em um espaço que está esperando receber um array de strings.

Uma alternativa seria separar o código em várias strings, indicando os locais onde deveria haver quebra de linha. Porém, isso seria uma tarefa mais trabalhosa do que pode parecer e ainda haveria a preocupação com a indentação do código.

Felizmente há uma ferramenta para nos ajudar nesse processo. Com o Snippet Generator, é possível escrever o código de maneira convencional e ele se preocupa em convertê-lo para a estrutura do snippet.

No exemplo a seguir, definimos um título, o prefixo e o corpo do código e obtemos uma estrutura pronta. Sem a definição do scope, o snippet fica acessível para todo tipo de arquivo. Se esse não for um comportamento desejado, é importante acrescentar o scope manualmente dentro do seu arquivo.

![[2022-09-16 (3).png]]

Sintaxe para a criação do snippet

É comum que você queira criar um snippet mais flexível. Uma maneira de alcançar esse objetivo é definir pontos do código que não serão fixos. Ou seja, em cada contexto específico, o usuário poderá complementar o snippet da maneira que quiser. Assim, o VSCode possibilita definir os locais de parada do cursor e o usuário poderá navegar entre eles mais rapidamente utilizando a tecla Tab.

Esses pontos serão definidos digitando $1, $2, etc., e o cursor irá seguir em ordem crescente. Além disso, o último local do cursor será definido por $0 . Os pontos que tiverem a mesma identificação serão atualizados simultaneamente. Vamos ver um exemplo:

"body": [
"function $1() {",
" return(",
" <$1Container>",
" $0",
" <$1Container/>",
" )",
"}",
"",
"const $1Container = styled.div``",
"",
""
],

O exemplo acima é o body de um snippet que cria um componente funcional e um componente para estilização com o Styled Components.

O primeiro ponto desse código que será modificável é o título do componente. Além disso, esse título deverá aparecer no componente de estilização e ser retornado como container do componente na função. Ou seja, teríamos que digitar esse texto 4 vezes, se não fosse a possibilidade de marcar o local do cursor com $1 e digitá-lo nos 4 locais simultaneamente.

Definição de estrutura

Definido o nome do componente, o próximo passo seria definir sua estrutura. Por isso, a posição final do cursor foi definida com $0 no return da função dentro da tag pai. Dessa forma, precisaríamos apenas dos seguintes passos para iniciar a criação desse componente:

  1. Chamar o snippet com o prefix;
  2. Digitar o nome do componente + Tab + começar a criar sua estrutura HTML.

Outra maneira de deixar o código mais flexível é utilizando as variáveis do VSCode. As variáveis nos permitem acessar informações importantes que poderão ser úteis para a criação do snippet. Para utilizá-las, basta digitar ${name}, onde name é o nome da variável.

Outra possibilidade é definir um valor padrão para quando a variável não tiver definida com ${name:default}. Alguns exemplos de variáveis são:

  • TM_FILENAME: o nome do arquivo em que o snippet está sendo chamado;
  • TM_DIRECTORY: o caminho do diretório em que o snippet está sendo chamado;
  • TM_SELECTED_TEXT: o texto selecionado no momento em que o snippet é chamado;
  • CURRENT_YEAR: ano atual (há outras variáveis relacionadas à data).

As demais variáveis podem ser visualizadas nesta documentação. Os valores das variáveis também podem ser modificados através de expressões regulares. Essa situação acontece, por exemplo, quando se deseja remover a extensão do nome do arquivo.

Criando nosso primeiro snippet

Agora é hora de colocar a mão na massa! Vamos aplicar esses conhecimentos para criar 2 snippets no VSCode com blocos de código familiares a quem desenvolve aplicações com o React: o componente funcional e um componente para estilização com o Styled Components.

Componente funcional

Vamos utilizar a ferramenta de geração de snippets vista anteriormente. O primeiro passo é definir o seu nome. Esse nome não deverá ser tão grande, já que ele será exibido no momento em que o prefix for digitado.

No entanto, ele deverá ser bem descritivo, para que possamos diferenciá-lo de outros snippets. O nome utilizado aqui será “Create React Function Component”.

Definição do prefix

O próximo passo é definir o seu prefix. Uma sugestão é utilizar as primeiras letras do nome do snippet. Assim, teremos “crfc”. Vamos copiar e colar essa estrutura inicial dentro do nosso JSON global.

Ainda precisamos definir o scope do nosso snippet. Como eu desejo acessá-lo apenas em projetos de React sem TypeScript, a escolha natural aqui para o scope é “javascript, javascriptreact”. Caso deseje verificar como o nome das extensões foi definido no VSCode para ser reconhecido no scope, acesse as opções com Ctrl + Shift + P e selecione “Snippets: Configure User Snippets”. Dessa forma, será exibida uma lista com as extensões.

Pensando nisso, essa é a nossa estrutura inicial:

"Create React Function Component": {
"scope": "javascript, javascriptreact",
"prefix": "crfc",
"body": [
"",
"",
""
],
"description": "Create React Function Component"
}

Criação do body

Vamos agora nos dedicar à criação do body. Uma estrutura “crua” de um componente seria:

function Component() {
return(
<div>
</div>
);
}
export default Component;

Perceba, no entanto, que o nome do componente já vem definido, assim como a tag “div”, e esses são elementos que certamente desejaremos mudar, dependendo de onde esse código estiver sendo utilizado.

Então, é mais interessante que o nome do componente e a tag do container não sejam definidos. E, ao invés disso, o usuário tenha acesso mais fácil a esses locais para que possa manipular o código. Portanto, vamos definir locais de parada para o cursor.

"body": [
"function $1() {",
" return(",
" <$2>",
" $0",
" </$2>",
" );",
"}",
"",
"export default $1;"
],

Note agora que no local do nome do componente tem $1, que também aparece na linha do export, para que o usuário digite apenas uma vez. Esse é o primeiro ponto de parada do cursor.

Tag HTML

O próximo ponto é na tag HTML do container para que o usuário possa escolher por si mesmo qual tag utilizar. E o último ponto de parada é o $0, permitindo que a estrutura do componente seja desenvolvida sem a necessidade de nenhum click adicional no mouse.

Outra forma de deixar o nome do componente flexível é utilizando as variáveis. Para o caso em que o nome do arquivo é o mesmo que o nome do componente, basta utilizar a variável “TM_FILENAME_BASE”, que retorna o nome do arquivo sem sua extensão.

"body": [
"function ${TM_FILENAME_BASE}() {",
" return(",
" <$1>",
" $0",
" </$1>",
" );",
"}",
"",
"export default ${TM_FILENAME_BASE};"
],

Agora, se você utiliza uma estrutura de diretório diferente, mas também muito comum, de criar uma pasta com o nome do componente e chamar o arquivo do componente de “index.jsx”, outra variável deverá ser utilizada: a TM_DIRECTORY.

![[2022-09-19 (1).png]]

O problema é que essa variável não retorna apenas o nome do diretório, mas todo o seu caminho. Por isso, é necessário fazer uma pequena transformação utilizando uma expressão regular para que seja retornado apenas o seu nome.

Sem entrar nos detalhes de como funcionam as expressões regulares, podemos utilizar a variável ${TM_DIRECTORY/^.+[\\/\\\\]+(.*)$/$1/}.

Dessa forma, o snippet ficará assim:

"Create React Function Component": {
"scope": "javascript, javascriptreact",
"prefix": "crfc",
"body": [
"function ${TM_DIRECTORY/^.+[\\/\\\\]+(.*)$/$1/}() {",
" return(",
" <$1>",
" $0",
" </$1>",
" );",
"}",
"",
"export default ${TM_DIRECTORY/^.+[\\/\\\\]+(.*)$/$1/};"
],
"description": "Create React Function Component"
}
![[criar componente.gif]]

Componente de estilização

Para criar o componente de estilização com o Styled Components, vamos aplicar a mesma estratégia. Dessa vez, o nome do snippet será “Create Styled Component” e o seu prefix será “csc”. Serão acrescentadas ao scope as extensões “typescript”(.ts) e “typescriptreact” (.tsx).

Então, teremos a seguinte estrutura inicial:

"Create Styled Component": {
"scope": "javascript, javascriptreact, typescript, typescriptreact",
"prefix": "csc",
"body": [
"",
"",
""
],
"description": "Create Styled Component"
}

Para o nome do componente, utilizaremos também a variável TM_DIRECTORY modificada pela expressão regular utilizada anteriormente. Além disso, a tag HTML do componente deverá ser flexível, portanto, o primeiro ponto de parada do cursor será no local da tag.

Por fim, o cursor deve estar posicionado de forma que o usuário possa iniciar a configuração de estilos facilmente. O snippet final ficará assim:

"Create Styled Component": {
"scope": "javascript, javascriptreact, typescript, typescriptreact",
"prefix": "csc",
"body": [
"import styled from 'styled-components';",
"",
"const ${TM_DIRECTORY/^.+[\\/\\\\]+(.*)$/$1/}Container = styled.$1`",
" $0",
"`",
"",
"export default ${TM_DIRECTORY/^.+[\\/\\\\]+(.*)$/$1/}Container;"
],
"description": "Create Styled Component"
}
![[styled.gif]]

Snippet para integrar o componente funcional ao componente de estilização

Se estivermos criando um componente que será estilizado com o Styled Components, é certo que o arquivo com a estilização será importado e, muito provavelmente, a tag HTML retornada por esse componente será o próprio componente criado pelo Styled Components. Assim, podemos criar um snippet de componente que já prevê essa estilização.

O nome deverá especificar que esse é um componente funcional que já importa o componente de estilização. Portanto, um nome possível para esse snippet é “Create React Function Component with Styled Components” e o prefix será “crfcsc”. À estrutura do body será adicionado o import e a tag do componente de estilização criado.

Portanto, o resultado será o seguinte snippet.

"Create React Function Component with Styled Components": {
"scope": "javascript, javascriptreact",
"prefix": "crfcsc",
"body": [
"import ${TM_DIRECTORY/^.+[\\\\\\\\/\\\\\\\\\\\\\\\\]+(.*)$/$1/}Container from
\"./styles\";",
"",
"function ${TM_DIRECTORY/^.+[\\\\\\\\/\\\\\\\\\\\\\\\\]+(.*)$/$1/}() {",
" return(",
" <${TM_DIRECTORY/^.+[\\\\\\\\/\\\\\\\\\\\\\\\\]+(.*)$/$1/}Container>",
" $0 ",
" </${TM_DIRECTORY/^.+[\\\\\\\\/\\\\\\\\\\\\\\\\]+(.*)$/$1/}Container>",
" );",
"}",
"",
"export default ${TM_DIRECTORY/^.+[\\\\\\\\/\\\\\\\\\\\\\\\\]+(.*)$/$1/};"
],
"description": "Create React Function Component with Styled Components"
}
![[function com styled.gif]]

Veja também:

Como criar CRUD Básico com NestJS, GraphQL e MySQL

Próximos passos

Os snippets criados neste artigo têm como finalidade apenas ilustrar o potencial dessa ferramenta para aumentar a produtividade no desenvolvimento. Utilize a documentação e as dicas fornecidas aqui para criar snippets no VSCode de acordo com suas necessidades. Uma sugestão para praticar é reutilizar esses snippets para o caso com TypeScript.

Autor: Vinícius Ribeiro.

O post Como criar snippets no VSCode para agilizar o desenvolvimento em React apareceu primeiro em Luby Software.

]]>
“Code Smell”: identificando problemas no código https://luby.com.br/desenvolvimento/software/conceitos/code-smell/ Tue, 27 Sep 2022 18:19:16 +0000 https://luby.com.br/?p=12250 Criado por Kent Beck, engenheiro de software americano e criador do Extreme Programming e Test Driven Development, o “Code smell” é um termo para dizer que algo no código “não está cheirando bem”. Um code smell costuma ser uma evidência de que há um problema no código-fonte de uma aplicação. Porém, ele não é necessariamente […]

O post “Code Smell”: identificando problemas no código apareceu primeiro em Luby Software.

]]>
Criado por Kent Beck, engenheiro de software americano e criador do Extreme Programming e Test Driven Development, o “Code smell” é um termo para dizer que algo no código “não está cheirando bem”.

Um code smell costuma ser uma evidência de que há um problema no código-fonte de uma aplicação. Porém, ele não é necessariamente um bug no sistema, e sim um indicativo de que as boas práticas de design não foram aplicadas neste sistema. Isso pode impactar negativamente todo o desenvolvimento e dificultar qualquer alteração futura que precise ser feita.

O termo foi cunhado em 1990, mas ganhou popularidade em 1999, no livro de Martin Fowler: “Refatoração: aperfeiçoando o design de códigos existentes”, no qual o autor utiliza o code smell como uma forma padronizada de detectar e aplicar refatorações no código.

Apesar de nada superar uma intuição bem treinada para saber quando realizar uma refatoração necessária, ter conhecimento do code smell auxiliará a ter um rumo quando eles ocorrerem. Tendo isto em vista, trouxemos alguns dos principais code smells com os quais vocês podem se deparar e alguns exemplos de como resolvê-los.

Mysterious Name (Nome Misterioso)

Enquanto programadores, eu diria que dar nome a algo é uma das tarefas que mais realizamos na nossa profissão, mas dar bons nomes, apesar de em alguns casos ser difícil, se mostra crucial para um código bem escrito.

Alguns programadores ainda consideram que aplicar refatoração em nomes seja uma perda de tempo. Entretanto, ter uma classe, função ou variável com nomes claros quanto ao seu objetivo e função pode evitar horas de dor de cabeça para entender o intuito de algo no código.

Duplicate Code (Código Duplicado)

Um dos code smells mais comuns e mais fácil de ser reconhecido é o código duplicado. Em sua essência, ele é um trecho de código que faz a mesma coisa, ou praticamente a mesma coisa, existindo em dois lugares diferentes do seu sistema. Veja o exemplo:

Como utilizar Code Smells parte 1.

O problema em ter código duplicado acontece quando é preciso alterar algo em seu funcionamento. Assim, é preciso encontrar e realizar a alteração na cópia duplicada do código, se quiser que ambos tenham o mesmo comportamento.

Entretanto, é simples resolver a duplicidade de código: mantenha em apenas um lugar no código, fazendo uso de funções ou loops.

Como utilizar Code Smells parte 2.

Comments (Comentários)

Comentários por si só não são um code smells. Muito pelo contrário, comentários são recomendados, eles te auxiliam a descrever o que está acontecendo ou explicar por que você fez algo, auxiliando no bom entendimento (tanto para você quanto para alguém que vai passar por ele depois).

O problema acontece quando comentários são utilizados para disfarçar código ruim, sendo utilizados de maneira supérflua em casos em que uma refatoração poderia render um melhor resultado.

Como utilizar Code Smells parte 3.

No exemplo, podemos notar que o código por si só não é capaz de explicar o que está sendo feito. Por isso, são utilizados comentários. Assim, uma simples refatoração nos nomes das variáveis podem ajudar o código a nos contar melhor a história.

Como utilizar Code Smells parte 4.

God Object (Classe Grande)

Outro code smell muito comum são as classes grandes. Isto é, classes que possuem muitos métodos ou propriedades que, apesar de parecer fazer sentido estarem juntos, acabam por criar classes com muitas responsabilidades e que podem ser perigosas para o seu sistema.

Essas classes surgem pois é muito mais simples atribuir um novo método a uma já existente do que criar uma nova. Diante disso, fica a dica: faça um esforço e separe bem as responsabilidades de cada classe.

Como utilizar Code Smells parte 5.

Todavia, devemos analisar e refatorar essa classe, seja extraindo as funções que não lhe pertencem e criando a partir delas uma nova classe, ou identificando métodos pouco utilizados e extraindo para uma subclasse que só será necessária nesses raros casos.

Como utilizar Code Smells parte 6.

Long Parameter List (Lista Longa de Parâmetros)

Apesar de não haver um padrão escrito, considera-se que 3 ou 4 parâmetros para uma função já estejam de bom tamanho. Ter muitos parâmetros dificulta para quem está lendo o código entender o que aquela função ou método faz. Além de ser difícil lembrar a ordem em que cada parâmetro deve ser disposto.

Como utilizar Code Smells parte 7.

Algumas refatorações simples podem ser aplicadas em casos como estes. Dessa forma, é preciso apenas analisar o que está acontecendo.

Caso alguns dos argumentos sejam resultados de uma chamada de métodos de outras classes, remova-os como parâmetros e faça a chamada dos métodos dentro da função. Se muitos dos parâmetros são propriedades de um objeto, considere passar o objeto inteiro como parâmetro. Porém, caso sejam diversas propriedades de diversas fontes, é possível criar um novo objeto que servirá como parâmetro desta função.

Como utilizar Code Smells parte 8.

Após refatorar uma lista longa de parâmetros, você terá um código mais limpo e de fácil leitura. Além disso, durante o caminho é possível que você identifique algumas duplicações de código que são comuns em casos como este.

Ferramentas

Agora que você já conhece alguns dos principais code smells, vamos conferir algumas ferramentas que irão te auxiliar a perceber aqueles odores que passaram despercebidos pelo seu olfato:

PMD

PMD é um programa open-source que atua como um analisador de código-fonte, identificando e relatando problemas encontrados. Apesar de já ter um conjunto de regras pré-definidos, ele apresenta também suporte a regras personalizadas.

O objetivo do PMD não é relatar problemas durante a compilação do código, mas sim ineficiências ou maus hábitos de programação. Por exemplo, variáveis não utilizadas, objetos criados desnecessariamente, dentre outros que, apesar de não impedirem o sistema de funcionar, podem reduzir o desempenho e dificultar a manutenção (caso se acumulem).

SonarQube

SonarQube é um programa open-source desenvolvido pela SonarSource que realiza uma inspeção contínua na qualidade do código e gera relatórios com análise de bugs, cobertura de código e code smells em 29 linguagens de programação. Este programa oferece relatórios para duplicação de código, padronização de código, cobertura de código por testes, comentários, bugs e recomendações de segurança.

Como utilizar Code Smells parte 9.

Conclusão

Tendo o conhecimento do que é um code smell, como identificá-los e tratá-los, que tal dar uma busca naquele seu código que você não mexe há um tempo. Ou até mesmo no que você está escrevendo agora e já começar a pôr em ação essas novas boas práticas? Tenho certeza que vai te poupar muito tempo lá na frente!

Veja também:

Boas práticas de commits assinados e proteção de branches

Autor: Higor Koakovski.

O post “Code Smell”: identificando problemas no código apareceu primeiro em Luby Software.

]]>
A importância da Abstração na Programação Orientada a Objetos https://luby.com.br/desenvolvimento/software/conceitos/abstracao-orientada-a-objetos/ Tue, 20 Sep 2022 18:27:29 +0000 https://luby.com.br/?p=12239 Quando se fala em paradigmas de linguagem de programação, a Programação Orientada a Objetos (POO) é, com certeza, um dos modelos mais populares entre os desenvolvedores. Ela possui quatro principais pilares: Abstração; Encapsulamento; Herança; e Polimorfismo. Neste artigo, vamos falar sobre o conceito Abstração, utilizando um exemplo prático para ressaltar sua importância. Abstração na Programação […]

O post A importância da Abstração na Programação Orientada a Objetos apareceu primeiro em Luby Software.

]]>
Quando se fala em paradigmas de linguagem de programação, a Programação Orientada a Objetos (POO) é, com certeza, um dos modelos mais populares entre os desenvolvedores. Ela possui quatro principais pilares: Abstração; Encapsulamento; Herança; e Polimorfismo.

Neste artigo, vamos falar sobre o conceito Abstração, utilizando um exemplo prático para ressaltar sua importância.

Abstração na Programação Orientada a Objetos

Embora alguns materiais de estudo deixem um pouco de lado a Abstração na Programação Orientada a Objetos para focar nos demais pilares, é importante frisar que a Abstração é o pontapé inicial dentro de qualquer linguagem Orientada a Objetos

O conceito de abstração consiste em esconder os detalhes de algo, no caso, os detalhes desnecessários. Dessa forma, todos os outros pilares serão desenvolvidos a partir da Abstração.

Como abstrair um modelo/entidade que faça sentido como um objeto?

Para facilitar o processo de abstração na Programação Orientada a Objetos, definimos 3 princípios para uma abstração concisa, são eles:

  • O que o objeto precisa ser?
  • O que ele faz?
  • E o que ele deve ter?

No exemplo a seguir, utilizaremos a linguagem C# para abstrair um personagem de RPG para um objeto.

Primeiro princípio: o que o objeto precisa ser?

public class Personagem
{
}

Neste caso, queremos que o personagem seja uma entidade que possa causar e sofrer dano.

Segundo princípio: o que o objeto faz?

public class Personagem
{
public void Atacar(Personagem adversario)
{
}
}

O personagem atacará outro personagem diminuindo a quantidade de vida do adversário com base em seu poder de ataque, e o personagem atacado receberá o dano consequente.

Terceiro princípio: o que o objeto deve ter?

public class Personagem
{
public string Nome { get; set; }
public int PoderDeAtaque { get; set; }
public int QuantidadeDeVida { get; set; }

public void Atacar(Personagem adversario)
{
adversario.QuantidadeDeVida -= PoderDeAtaque;
}
}

O personagem deve ter um nome pelo qual será identificado. Além disso, para atacar, queremos que o personagem possua um medidor de poder e, para receber dano, o personagem terá uma quantidade limitada de vida.

Abstração: criação de objeto de forma sucinta e coesa

Nota-se que, com estes 3 princípios, podemos criar um objeto de forma sucinta e coesa, sem utilizar de atributos os métodos desnecessários para o contexto. É importante que, na hora de utilizar este objeto em um projeto real, o seu código POO deva sempre buscar o baixo acoplamento. Ou seja, a independência entre um objeto e outro.

Neste artigo, fizemos este exemplo básico criando uma classe chamada Batalha, em que movemos o método Atacar para ela. Dessa forma, haverá apenas um objeto responsável por realizar os ataques dos personagens, já que a ideia é que o personagem seja apenas um modelo e que o combate seja gerido por uma classe a parte.

public class Batalha<T> where T : Personagem
{
public void Atacar(T quemAtaca, T quemRecebeDano)
{
quemRecebeDano.QuantidadeDeVida -= quemAtaca.PoderDeAtaque;
}
}

Conclusão

A Abstração na Programação Orientada a Objetos acontece bem antes do código e é muito importante que seja bem definida. Assim, facilitará a arquitetura do projeto como um todo. Para uma ideia ser bem executada, antes ela precisa ser bem estruturada.

Além disso, lembre-se de estudar também sobre os outros pilares da orientação a objetos. Então, aqui vão algumas sugestões de conteúdos sobre este mesmo tema: https://www.macoratti.net/oo_conc2.htm.

Veja também:

Como identificar problemas no código

Conceitos de programação que você precisa conhecer

Autor: Marcelo Wesley.

O post A importância da Abstração na Programação Orientada a Objetos apareceu primeiro em Luby Software.

]]>
Como configurar atalhos do GIT https://luby.com.br/desenvolvimento/software/como-configurar-atalhos-do-git/ Wed, 10 Aug 2022 13:43:09 +0000 https://luby.com.br/?p=12159 Você está cansado de escrever repetidamente “git add .” && “git commit -m” “seu commit””? Pois bem, neste artigo, vamos aprender a utilizar atalhos do GIT. Os atalhos do GIT permitirão que possamos otimizar o trabalho do dia a dia, resultando em melhor experiência e principalmente no aumento de produtividade. [adrotate banner=”4″] Como utilizar atalhos […]

O post Como configurar atalhos do GIT apareceu primeiro em Luby Software.

]]>
Você está cansado de escrever repetidamente “git add .” && “git commit -m” “seu commit””? Pois bem, neste artigo, vamos aprender a utilizar atalhos do GIT.

Os atalhos do GIT permitirão que possamos otimizar o trabalho do dia a dia, resultando em melhor experiência e principalmente no aumento de produtividade.

[adrotate banner=”4″]

Como utilizar atalhos do GIT?

Toda a lógica dos atalhos consiste na criação de nossos próprios comandos do GIT. Assim, teremos comandos diferenciados e que agem conforme sua preferência, por exemplo:

~: git c “feat: melhorando sua produtividade com o GIT”

No comando acima, na minha máquina, ele executa dois comandos, o “git add .” e “git commit -m “feat: melhorando sua produtividade com o GIT””. Dessa forma, não precisamos mais escrever os dois comandos, mas sim apenas um.

Iniciando a configuração

Então, vamos lá! Primeiramente, abra seu terminal e digite o seguinte comando:

~: git config --global -e

Em seguida, você irá abrir o seu editor de preferência. No meu caso, deixei o arquivo bem cru, então ele está assim:

Como configurar atalhos do GIT Luby Software

Neste caso, não temos a sessão [alias]. Dessa forma, vou adicioná-la abaixo das configurações de [user], da seguinte forma:

Como configurar atalhos do GIT Luby Software

Após declararmos a sessão de Alias, podemos criar nosso primeiro atalho. Por isso, vamos começar com o comando do GIT que mostra o status. Porém, iremos fazer com que ele retorne o status de uma forma mais enxuta, utilizando o parâmetro “-s”, segue o código:

s = !git status -s

Como configurar atalhos do GIT Luby Software

Em seguida, vamos adicionar o comando que demonstrei no início deste artigo, aquele que adiciona os arquivos e “commita” logo em seguida, sendo ele:

c = !git add --all && git commit -m

Como configurar atalhos do GIT Luby Software

Obs.: lembre-se que, caso não queira adicionar todos os arquivos alterados para o processo de commit, você deve incluir individualmente os arquivos que deseja com o comando tradicional git add [nome do arquivo] e depois executarmos o comando git commit -m “[Mensagem Descritiva]”. Ou seja, o processo tradicional.

Git log

O próximo comando será o “git log”, usaremos a opção “—pretty=format:” para deixarmos o nosso log mais bonito:

l = !git log --pretty=format:'%C(blue)%h%C(red)%d %C(white)%s - %C(cyan)%cn, %C(green)%cr

Como configurar atalhos do GIT Luby Software

O código utilizado segue a seguinte lógica:

  • %h: o percentual com a letra h minúscula irá apresentar o hash reduzido do commit;
  • %d: o percentual com a letra d minúscula irá mostrar a branch, e também a tag (caso exista) do commit;
  • %s: o percentual coma letra s minúscula (de subject) irá demonstrar a mensagem do commit;
  • %cn: nome da pessoa que realizou o commit;
  • %cr: a data relativa do commit.

Também utilizamos a opção de mostrar cores diferentes para cada coluna, o que facilita a visualização. Para isso, utilizamos o parâmetro % com a letra C maiúscula (%C), seguido da cor que desejamos entre parênteses (blue).

Segue um exemplo de como fica o comando:

Como configurar atalhos do GIT Luby Software

Veja também:

Como criar um projeto com Vite

Tutoriais de desenvolvimento de software

Conclusão

Assim concluímos a configuração dos atalhos do GIT que mais utilizamos. Lembrando que existem diversas outras opções de configuração, que podem ser verificadas na documentação oficial do GIT clicando aqui.

Autor: Paulo Santana.

[adrotate banner=”5″]

O post Como configurar atalhos do GIT apareceu primeiro em Luby Software.

]]>
Introdução ao ReactJs: o que saber antes de iniciar os estudos? https://luby.com.br/desenvolvimento/software/introducao-ao-reactjs/ Wed, 03 Aug 2022 21:28:59 +0000 https://luby.com.br/?p=10426 [vc_row][vc_column][vc_column_text]O ReactJS é um dos mais famosos frameworks Javascript que se tem na atualidade. Por isso, neste artigo, vamos trazer a introdução ao ReactJS, abordando tudo o que você precisa saber para começar a utilizar este framework. O ReactJS foi criado com o propósito de criar interfaces. Assim, cada elemento em tela pode ser agrupado […]

O post Introdução ao ReactJs: o que saber antes de iniciar os estudos? apareceu primeiro em Luby Software.

]]>
[vc_row][vc_column][vc_column_text]O ReactJS é um dos mais famosos frameworks Javascript que se tem na atualidade. Por isso, neste artigo, vamos trazer a introdução ao ReactJS, abordando tudo o que você precisa saber para começar a utilizar este framework.

O ReactJS foi criado com o propósito de criar interfaces. Assim, cada elemento em tela pode ser agrupado e utilizado como um componente. O framework é também uma biblioteca fácil de iniciar e eficiente para a criação de SPAs (Single Page Applications), interfaces de usuários. Além disso, o ReactJS é utilizado pelas grandes empresas do mercado atual: Netflix, Facebook, Amazon Videos, Airbnb, dentre várias outras.

[adrotate banner=”4″]

Essa biblioteca tem um enorme poder nas mãos. Sua agilidade em aplicações complexas é notável, pois quando se trabalha com páginas web, os scripts que são executados em segundo plano acabam se tornando um gargalo na renderização e execução da página por inteiro.

Entretanto, como o ReactJs trata os elementos em tela como componentes, isso permite fazer atualizações em tela apenas daquele elemento que sofreu alteração, ao invés de se preocupar em recarregar toda a página. Isso é um dos recursos mais fascinantes dessa ferramenta. Então vamos conferir tudo sobre a introdução ao ReactJS?

A forma de código utilizada em React é o JSX, que é uma forma combinada de código Javascript e XML (eXtensible Markup Language). Dessa forma, não é considerada nem Javascript, nem XML, mas as semelhanças são notáveis:

Introdução ao ReactJS 1 - Exemplo de código escrito em JSX.
Introdução ao ReactJS 1 – Exemplo de código escrito em JSX.

Introdução ao ReactJS: por onde iniciar?

Na introdução ao ReactJS, o primeiro ponto de atenção é entender que o framework está apoiado nas ferramentas como: HTML (HyperText Markup Language), CSS (Cascading Style Sheet) e, certamente, Javascript. Esses são os blocos primordiais aos quais este framework se apoia. Isso porque esse “JSX”, que falamos anteriormente, se assemelha bastante à combinação dessas três ferramentas.

Portanto, a forma mais natural de se iniciar os estudos em uma ferramenta nova, como na introdução ao ReactJS, é justamente pelo começo: iniciando com HTML. Com essa ferramenta, vamos aprender sobre os elementos da página web, o que muitos consideram como o “esqueleto” do site.

Para ter um bom conhecimento da ferramenta não é preciso aprender necessariamente tudo o que ela fornece, mas é essencial ter um domínio sobre os tópicos abaixo:

HTML

Tags

O HTML apresenta uma quantidade vasta de tags, que são as estruturas que englobam o conteúdo que se deseja mostrar em tela.

Introdução ao ReactJS 2 - Exemplo de código em HTML.
Introdução ao ReactJS 2 – Exemplo de código em HTML.

No exemplo em questão, temos a uma tag “<h1>”, que representa uma tag de título de um texto ou da página de forma geral. Temos também as tags <p> e <span> , que são tags de textos, onde a primeira é utilizada para representar os parágrafos da página, e a segunda serve para dar ênfase à algum pequeno trecho do texto.

E, por último, tempos a tag “<div>”, que funciona como um contêiner para o conteúdo da nossa página, ela pode englobar o conteúdo textual, como apresentado acima, como também pode englobar conteúdos de imagens, ou até mesmo apenas para organizar o layout da página.

Esses são somente alguns exemplos, mas o HTML possui um leque gigantesco de tags: <footer>, <main>, <nav>, <header>, <address>, <code>, <ul>, <li>, dentre centenas de outras. Com isso, construímos o “esqueleto” da nossa aplicação web.

HTML Semântico

Com assuntos em alta como acessibilidade, usar as tags de forma correta, durante a construção da sua página web, é de extrema importância. Isso porque muitas pessoas que possuem deficiência visual fazem uso de leitores digitais que faz a leitura detalhada da página com base no arquivo HTML que está renderizando a página.

Dessa forma, ao utilizar a estrutura mais adequada na sua página, a pessoa com necessidades especiais pode entender com mais clareza o que está lendo, se aquele trecho da página é o cabeçalho, se é um parágrafo, se é o rodapé, etc. Por isso, temos as tags de valor semântico, como no caso da <header>, que vai delimitar o cabeçalho, <main>, que vai conter o conteúdo principal da página, <footer>, que vai apresentar o rodapé.

Usando como exemplo a imagem abaixo, conseguimos ter uma noção de como são distribuídas as tags com base no layout da página.

Introdução ao ReactJS 3 - Modelo simples de como podemos dividir os componentes de uma página em diferentes seções.
Introdução ao ReactJS 3 – Modelo simples de como podemos dividir os componentes de uma página em diferentes seções.

Existem diversas tags com poder semântico e esse é um assunto que merece uma atenção dedicada, pois vai gerar grande influência no nosso tópico seguinte. Para mais detalhes sobre HTML semântico, é altamente recomendado dar uma olhada nas documentações: w3schools.com e a developer.mozilla.org.

SEO

O SEO (Search Engine Optimization) é o mecanismo de busca do Google que faz o ranqueamento dos sites para definir quais domínios irão aparecer em primeiro lugar nas pesquisas feitas pelos usuários. O Google dá notas para os sites com base nas boas práticas pré-determinadas pelo Google.

E o HTML semântico é uma das formas de obter uma boa nota, além de adicionar as “meta tags” que veremos no próximo tópico. Por isso, é essencial ter noção de como melhorar o page rank da sua aplicação, para que seu domínio sempre apareça na primeira página de busca.

Meta Tags

As Meta Tags são pequenos trechos de código que indicam algumas informações sobre a página. Elas indicam quais os tipos de caracteres usados na página, o título da aplicação, descrições curtas sobre o conteúdo da página, instruções sobre como renderizar as dimensões dos elementos com base em diferentes dispositivos (móveis ou desktop).

Bem como podemos adicionar palavras-chaves que podem ajudar o Google a achar seu site com base nos termos utilizados pelos usuários no campo de pesquisa. Aqui temos alguns exemplos de meta tags:

Introdução ao ReactJS 4 - Exemplos de Meta Tags mais comuns.
Introdução ao ReactJS 4 – Exemplos de Meta Tags mais comuns.

Dentro da mesma área em que colocamos as nossas meta tags, também adicionamos as importações dos nossos arquivos de estilo “main.css”, assim como os nossos scripts “main.js”. Entretanto, é uma boa prática adicionar os scripts no fim do nosso código, mas ainda dentro da tag <body>:

Introdução ao ReactJS 5 - Localização mais adequada para se colocar os scripts.
Introdução ao ReactJS 5 – Localização mais adequada para se colocar os scripts.

Isso é devido ao fato do conteúdo em Javascript demorar um pouco mais para carregar, ao contrário dos elementos HTML e os estilos do CSS. Isso é outro fator que conta como boas práticas!

Estrutura de uma página

A estrutura de uma página HTML é bastante simples. Ela possui um esqueleto comum à toda aplicação web e é dividida nas tags, que englobam todo o conteúdo.

Introdução ao ReactJS 6 - Exemplo de uma estrutura básica de HTML
Introdução ao ReactJS 6 – Exemplo de uma estrutura básica de HTML

Dentro dela temos das tags <head> e <body>. A tag “head” recebe justamente os conteúdos das nossas meta tags, e a tag “body” vai receber todo o conteúdo que será mostrado na página. O elemento <!DOCTYPE> é um recurso que veio com a versão mais recente do HTML, ele indica que o código a seguir segue os padrões da última versão da linguagem, o HTML 5.

Entretanto, isso não é uma tag HTML, isso é apenas uma instrução para o navegador que indica o tipo de arquivo que ele está lidando. Por isso, ele é adicionado logo no começo. Já a tag <title> indica o título da página, aquele nome pequeno que aparece acima da aba, no navegador:

Introdução ao ReactJS 7 - Apresentando no navegador onde o conteúdo da tag "title" é apresentado.
Introdução ao ReactJS 7 – Apresentando no navegador onde o conteúdo da tag “title” é apresentado.

Formulários

Os formulários são parte essencial nas aplicações web, seja para criação de login, cadastro de usuários, campos de pesquisa ou em formulários de compras em sites de e-commerce. Independentemente do tipo de conteúdo do site, é possível que tenha, ao menos, um campo de formulário para inserir dados. É essencial dar uma atenção especial a esse tópico.

CSS

O CSS é responsável pela estilização da página. É ele quem dar cor, estilo e organização. Ele distribui os elementos em tela seguindo um determinado layout. Com, ele temos várias ferramentas essenciais no desenvolvimento web:

Seletores (classes, id)

Os Seletores servem para que possamos identificar qual elemento HTML especificamente nós queremos editar e aplicar às nossas propriedades de estilos. Para isso, adicionamos classes ou id, por exemplo, <header class=”container”> e <main id=”content”>. Segue abaixo imagem que mostra como selecionar cada um desses elementos, respectivamente:

Introdução ao ReactJS 8 - Exemplo de seleção de elementos usando classes e id, respectivamente.
Introdução ao ReactJS 8 – Exemplo de seleção de elementos usando classes e id, respectivamente.

Pseudo classes

As pseudo classes são palavras-chave que são adicionadas aos seletores e especifica um determinado estado do elemento selecionado. Seja quando passamos o mouse em cima do componente ou quando marcamos uma “checkbox”, podemos controlar esses estados.

Por exemplo, ao passar o mouse sob um botão, a cor de fundo seja alterada. Existem inúmeras pseudo classes e, com certeza, vai acrescer nas habilidades de estilização.

Flexbox e Grid

Essas duas ferramentas são amplamente utilizadas para desenhar o layout das páginas e organizar os elementos da melhor forma possível. Enquanto o flexbox torna o conteúdo de dentro do elemento contêiner mais flexível, o grid faz uso de “grades”, dividindo as dimensões do contêiner em quadrantes, onde cada elemento de dentro do grid possui tamanhos proporcionais.

Essas duas ferramentas são as principais para a estilização de qualquer página web atualmente. Dominá-las é de extrema importância!

Responsividade

A responsividade se faz muito presente no mundo em que vivemos, pois todo mundo carrega um “computador” no bolso diariamente. As pessoas estão mais acostumadas a utilizar o celular para consumir os conteúdos da internet e acessar as redes sociais. Contudo, com uma tela consideravelmente menor que a de um computador, é importante que os desenvolvedores pensem na criação de uma versão mobile de suas aplicações web.

Dessa forma, um usuário poderá acessar sua página tanto pelo dispositivo móvel (seja um celular ou tablet) quanto pelo desktop, e ainda assim não ter a sua experiência prejudicada. É aí onde entra o nosso próximo item.

Media Querie

O media querie é a expressão nativa do CSS que utilizamos para criar as nossas páginas responsivas com base no tamanho da tela do dispositivo. Dessa forma, podemos desenhar um layout completamente diferente dependendo da resolução do aparelho.

Segue abaixo um exemplo da aplicação de propriedades para quando a página for acessada por um dispositivo com resolução abaixo de “600px” (pixels) de largura.

Introdução ao ReactJS 10 - Aplicando media querie.
Introdução ao ReactJS 9 – Aplicando media querie.

Javascript

Com o Javascript, temos toda a parte lógica da nossa aplicação. Ele será responsável por observar os eventos em tela, as requisições a outros serviços da internet, além de ser o principal responsável pelas interações com o usuário. Seja em um evento de “click”, recarregamento de página, e demais funções que são executadas sem segundo plano.

É o Javascript que torna a página mais dinâmica, quase viva. E, para dominá-lo, é importante focar bem a atenção nos seguintes temas:

Tipos de dados

Os tipos de dados, como o próprio nome sugere, são toda variedade de dados que o Javascript consegue lidar, são eles: Number, String (caracteres), Object, Boolean (true or false), Null, Undefined e Arrays (reconhecido como um tipo de objeto, para o Javascript).

Operadores

Assim como qualquer outra linguagem de programação, o Javascript também possui os seus operadores aritméticos: / (divisão), * (multiplicação), + (adição), – (subtração). Bem como operadores de comparação, que servem para verificar se uma determinada condição é verdadeira ou falsa: == (igual), != (diferente), > (maior que), etc.

Para mais informações a respeito dos operadores, vale a pena dar uma olhada nesta documentação (clique aqui para acessar).

Arrays e seus métodos

Arrays é um objeto Javascript que se assemelha à uma lista. Nos Arrays, podemos armazenar uma série de dados e informações. Os métodos de arrays servem para manipular essa lista de itens da forma que desejarmos. Podemos fazer uma filtragem, onde retiramos da lista alguns itens de um determinado tipo, podemos mapear a lista e transformar os elementos de dentro dela, retornando um segundo array completamente diferente do anterior.

Dominar a manipulação de arrays e compreender com profundidade os seus métodos é um dos passos mais importantes para a introdução ao ReactJS. Confira o exemplo de um array e a aplicação do método de “map”:

Introdução ao ReactJS 11 - Criação de array e aplicação do método "map()" .
Introdução ao ReactJS 10 – Criação de array e aplicação do método “map()” .

DOM

O DOM (Document Object Model) é a representação dos elementos que compõem todo o conteúdo de uma página web. Ele é responsável por exibir na tela o conteúdo HTML, CSS e pode ser alterado e manipulado com Javascript.

Ter uma boa noção dos objetos que compõem a janela do seu navegador é de suma importância para o seu desenvolvimento na introdução ao ReactJS, já que essa é uma ferramenta majoritariamente direcionada à web.

Objetos

Os Objetos em Javascript são como uma coleção de propriedades que possuem um nome e um valor, e cada propriedade é separada por vírgula. De forma grosseira, podemos fazer uma comparação com os Arrays. Porém, os Objetos possuem um nome (chave) para cada elemento (valor) que está dentro dele.

Os valores atribuídos à uma propriedade dentro de um objeto pode ser de qualquer tipo: Boolean, String, uma função, Number, etc. Veja um exemplo de um objeto:

Introdução ao ReactJS 12 - Exemplo de um objeto em javascript.
Introdução ao ReactJS 11 – Exemplo de um objeto em javascript.

Funções

Funções são componentes fundamentais em Javascript. Uma função é um conjunto de instruções ou tarefas, que serão executadas assim que a função for chamada. Primeiro criamos a função, logo em seguida escolhemos quando queremos que ela seja executada, pode ser após um evento de “click”, pode ser ao recarregar página.

Enfim, cabe ao programador/ programadora decidir como e onde melhor aplicá-las. E, assim como Arrays e Objetos, as funções são protagonistas principais quando se trata de ReactJs. Esses três itens devem ser estudados com muita atenção, pois serão utilizados até exaustão.

Introdução ao ReactJS 13 - Exemplo de função que recebe um objeto e o retorna em tela.
Introdução ao ReactJS 12 – Exemplo de função que recebe um objeto e o retorna em tela.

API

As APIs (Application Programming Interfaces) são como “transportadores” que levam e trazem informações (dados). Elas funcionam como intermediários entre o front-end e o back-end. Assim, o front-end faz um pedido (requisição) ao back-end, por meio da API, que é responsável pela comunicação. Então, o back-end faz uma consulta ao banco de dados, faz uma varredura e busca a informação requisitada.

Após isso, retorna a resposta (response) para a API, que logo em seguida devolve a informação ao front-end para que seja mostrado em tela. Tudo isso ocorre em questão de milésimos de segundos. Atualmente, grande parte da aplicações web funcionam por meio de APIs, onde podemos ter um conteúdo dinâmico e atualizar as informações em página de forma automática.

ECMAScript 6

O ECMAScript é o nome oficial da linguagem que conhecemos como Javascript. E a sexta versão da linguagem é importante por conta da padronização que o Javascript sofreu no ano de 2015. Depois disso, vieram diversas atualizações, novos métodos para trabalhar com Arrays, Objetos, além de mais funcionalidades. Portanto, para se manter atualizado na linguagem, é importante iniciar os estudos em ECMAscript da versão 6 em diante.

Introdução ao ReactJs de fato

Finalmente chegamos à introdução ao ReactJS e por onde iniciar os estudos. Uma vez que você já possui um conhecimento sólido em HTML, CSS e Javascript, prosseguir com React não será uma barreira, pelo contrário, será extremamente intuitivo. A seguir, podemos conhecer um pouco mais sobre os alicerces que apoiam o desenvolvimento web em ReactJs.

Entendendo JSX

A sintaxe do JSX, por mais que tenha suas peculiaridades, é natural de se entender e utilizá-la. Isso porque, dentro do código JSX, nós utilizamos tags HTML como se estivéssemos trabalhando com HTML puro. Não muda em nada a forma de escrever, uma <div> continua tendo as mesmas propriedades, um <p> funciona da mesma forma.

A diferença é que não estamos escrevendo isso dentro de um arquivo .html, mas sim como retorno de uma função em Javascript. Entretanto, isso é uma vantagem, pois podemos passar dados (props) entre funções, que dentro do JSX as tratamos como componentes.

Props

As props são propriedades que podemos passar entre componentes. Como no React as nossas funções retornam JSX, podemos importar e exportar componentes e passar propriedades para eles por meio de props. Dessa forma, nós importamos um determinado componente para a nossa página e escrevemos nele uma propriedade como se estivéssemos um atributo em uma tag HTML.

Introdução ao ReactJS 14 - Passando propriedades e valores por meio de Props para outros componentes.
Introdução ao ReactJS 13 – Passando propriedades e valores por meio de Props para outros componentes.

useState

O useState é uma funcionalidade (Hook) especifica do React que nos permite guardar o estado de um componente, variável e componente de função. Ele armazena um determinado valor inicial que foi atribuído a ele. Porém, quando queremos alterar o valor que está contido nesse hook, atribuímos por meio de uma função, ao invés de utilizarmos a forma padrão de atribuição de variáveis.

Introdução ao ReactJS 15 - Utilizando useState para alterar o valor da variável "language".
Introdução ao ReactJS 14 – Utilizando useState para alterar o valor da variável “language”.

Hooks

Assim como o useState, existem vários outros Hooks que tornam o React um framework especial. Aprender a trabalhar com esses Hooks é o que diferencia um bom programador React de um iniciante. Os mais utilizados são: useState, useEffect, useContext, useRef, useReducer, useCallback e useMemo. Existem vários outros, mas, dominando esses será mais do que suficiente para trabalhar com a maioria dos projetos.

Para entender melhor como cada um deles funciona e onde utilizá-los, é altamente recomendado ler a documentação (clique aqui para acessar).

Estilização (CSS, SASS, Styled Components)

A estilização no React é vasta, especialmente devido ao fato de todo código JSX ser renderizado dentro de um “index.html”. Isso nos permite utilizar ferramentas baseadas em CSS, como o SASS ou o próprio arquivo “.css” mesmo. Além disso, ele faz o uso de bibliotecas de estilos que aplicam as propriedades de estilização através do Javascript, como o Styled Components.

Bibliotecas

Como citado no tópico anterior, podemos fazer uso de bibliotecas externas em nosso projeto para melhorar a nossa produtividade e implementar funcionalidades que normalmente seriam trabalhosas ou muito complexas para se fazer manualmente. Ainda mais se a programadora/programador for iniciante.

Felizmente, o ReactJS é rico em bibliotecas para as demais finalidades: estilização; criação e validação de formulários; aplicação de modais e pop-ups; adicionar ícones no projeto; realizar requisições HTTP; etc. Essa última é tema do nosso próximo tópico.

Data fetching

As requisições de dados (Data fetching) são justamente as requisições que fazemos ao utilizar uma API. Podemos fazer uma requisição de dados para um arquivo XML dentro do nosso projeto, além de poder buscar dados dentro de um arquivo “.json”. As aplicações do Data fetching foram crescendo à medida que o uso e criação de novas APIs estão aumentando.

Fazemos requisições o tempo todo, seja durante o login em um site, no cadastro de um cliente em uma rede social ou quando fazemos uma pesquisa no campo de busca da Netflix, também estamos fazendo uma requisição de dados. O Javascript possui um método nativo de requisições HTTP que é o “fetch()”, mas o React possui uma biblioteca muito mais performática e famosa, o Axios.

Gerenciamento de Estados

O gerenciamento de um estado global de uma aplicação React surge quando precisamos passar uma mesma informação por vários componentes, passando por meio de Props, de elemento pai para filho. Mas quando temos um fluxo enorme de propriedades e tentamos passar isso por meio de Props, as informações ficam muito dependentes de um componente passar para outro.

Esse tipo de problema poderia ser facilmente evitado se qualquer componente pudesse consultar essas informações direto do arquivo que está exportando, ou de um arquivo que centraliza todas as informações que são utilizadas em mais de uma página.

Felizmente, existem soluções para isso: ferramentas que conseguem manter o controle do estado das informações em um nível acima de todos os componentes. Dessa forma, qualquer componente pode ter acesso a essas informações sem que seja necessário a passagem dos dados de pai para filho.

Pensando nisso, o React conta com ferramentas excelente para essa função, como é o caso do Context API, que já vem nativo no framework, o Redux e Zustand. Apesar de existirem mais algumas, essas são as principais, sendo o Context e Redux, as mais populares.

Da introdução ao ReactJS para o mercado de trabalho

Uma vez estudando toda a introdução ao ReactJS com dedicação, diariamente, colocando em prática todos os temas, aplicando em projetos, você já poderá começar a se inscrever para as vagas e entrar para o mercado de trabalho. Não é uma jornada fácil, e não existe atalhos, mas você pode seguir por um caminho com menores chances de falha. Então mão na massa e vamos codar!

Clique aqui e inscreva-se nas vagas da Luby!

Veja também:

Aprenda o que é data fetching!

Autor: Everson Vinicius Soares do Nascimento.

[adrotate banner=”5″][/vc_column_text][/vc_column][/vc_row]

O post Introdução ao ReactJs: o que saber antes de iniciar os estudos? apareceu primeiro em Luby Software.

]]>
Como criar CRUD Básico com NestJS, GraphQL e MySQL https://luby.com.br/desenvolvimento/software/crud-com-nestjs-graphql-e-mysql/ Tue, 26 Jul 2022 17:55:44 +0000 https://luby.com.br/?p=10279 Neste artigo, vamos aprender a criar um CRUD básico com NestJS, GraphQL e MySQL. Entretanto, antes de qualquer coisa, vamos entender o conceito de todos esses frameworks? Então, vamos lá! Segundo a documentação, NestJS é: Nest (NestJS) é mais um framework, voltado principalmente para construção de aplicações Node.js paraservidores Back-end. Dessa forma, uma das vantagens […]

O post Como criar CRUD Básico com NestJS, GraphQL e MySQL apareceu primeiro em Luby Software.

]]>
Neste artigo, vamos aprender a criar um CRUD básico com NestJS, GraphQL e MySQL.

Entretanto, antes de qualquer coisa, vamos entender o conceito de todos esses frameworks? Então, vamos lá!

Segundo a documentação, NestJS é:

Nest (NestJS) é mais um framework, voltado principalmente para construção de aplicações Node.js para
servidores Back-end. Dessa forma, uma das vantagens de se usar o NestJS é a alta escalabilidade do lado do servidor e a estrutura automática criada incialmente, seguindo os princípios do S.O.L.I.D.

[adrotate banner=”4″]

Como o NestJS utiliza TypeScript, é possível a criação de códigos fortemente tipados, mas também é possível utilizá-lo com JS puro.

A construção do código inicialmente combina elementos de OOP (Programação Orientada a Objetos), FP (Programação Funcional) e FRP (Programação Reativa Funcional). Além disso, o Nest faz uso de estruturas robustas de servidor HTTP como o Express (o padrão). Bem como, opcionalmente, pode ser configurado para usar o Fastify também!

O Nest fornece um nível de abstração acima dessas estruturas comuns do Node.js (Express/Fastify), mas
também expõe suas APIs diretamente ao desenvolvedor. Dessa forma, oferecendo aos desenvolvedores a liberdade de usar a infinidade de módulos de terceiros que estão disponíveis para a plataforma subjacente.

O que é GraphQL?

Segundo a documentação, GraphQL é:

GraphQL é uma linguagem de consulta para APIs de alto desempenho, relacionado ao tempo de consulta aos principais SGBDs. Dessa forma, o GraphQL fornece uma descrição completa e compreensível dos dados e requisições de sua API, oferecendo aos clientes o poder de solicitar exatamente o que eles precisam e nada mais!

Iniciando com NestJS e GraphQL

Primeiramente, para iniciar nosso projeto CRUD, iremos realizar todas as instalações necessárias para a criação do projeto.

Instalações necessárias

Extensões:

  1. JavaScript (ES6) code snippets
  2. Tabnine AI Autocomplete
  3. Path Intellisense
  4. Nodejs Snippets
  5. Material Icon Theme
  6. GitLens — Git supercharged
  7. Gitmoji
  8. Dracula Official
  9. ENV
  10. [Deprecated] Bracket Pair Colorizer 2
  11. Code Spell Checker

Projeto no github

Para visualizar o projeto deste artigo, clique neste link.

Instalações e start do projeto CRUD

  1. Abra o terminal do S.O como admin e execute o comando para instalação do NestJS de maneira Global ⇒ npm i -g @nestjs/cli
  2. Agora, execute o terminal em um local da sua preferência para criação do projeto, e digite o comando ⇒ nest new nest-api-withgraphql

Então, após executar o comando acima, a imagem abaixo descreve o que vocês devem visualizar de saída.

Como criar CRUD Básico com NestJS, GraphQL e MySQL Luby Software
Como criar CRUD Básico com NestJS, GraphQL e MySQL 1

3. Na imagem 1, escolha o seu gerenciador de pacotes favorito! Neste caso, vamos escolher o YARN.

Dessa forma, após as instalações para o NestJS estiverem finalizadas, a imagem abaixo descreve o que você deve visualizar de saída.

Como criar CRUD Básico com NestJS, GraphQL e MySQL Luby Software
Como criar CRUD Básico com NestJS, GraphQL e MySQL 2
  1. Na imagem 2, digite o comando cd .\NOME_DO_PROJETO para acessar a pasta criada com o projeto que definimos. Logo após entrarmos no projeto, vamos abri-lo no VSCode com o comando code .. Perfeito, agora podemos fechar o terminal!
  2. Para entender a estrutura criada, leia a documentação deste link.

Integrando o NestJS com Typeorm e MySql

Documentações de referência para projeto CRUD: https://docs.nestjs.com/techniques/database e https://typeorm.io/.

  1. Antes de tudo vamos abrir o terminal em nosso VSCode, através do comando CTRL + J
  2. Agora vamos fazer a instalação das dependências do typeorm e mysql:
    yarn add @nestjs/typeorm typeorm mysql2

Observação: vou fazer a instalação do mysql, porque este é o SGBD que mais utilizei na minha trajetória como programador, mas você pode utilizar outros, como postgresql, mssql, etc. É só fazer a instalação da lib e adicionar os parâmetros de conexão conforme apresentado no código abaixo.

Dentro do diretório src , vamos modificar o arquivo app.module.ts.

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm'
/*
Arquivo para importação dos módulos utilizados no projeto e conexão com o banco de dados!
Sejam bem-vindos ao coração da nossa API!
*/
@Module({
imports: [
TypeOrmModule.forRoot({
type: "mysql",
host: "localhost",
port: 3306,
username: "root",
password: "",
database: "graphql_database",
entities: [
"dist/**/*.entity{.ts,.js}"
],
synchronize: true
})
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule { }
  1. Importe o TypeOrmModule e adicione-o dentro do array de imports: []. Isso vai possibilitar a utilização do TypeORM em nossa API. A função forRoot() precisa receber alguns parâmetros de conexão com o banco, através de um json.

Caso queira saber mais sobre esses parâmetros, consulte a documentação neste link.

4. Ative os serviços de mysql e apache no XAMMP ou outro software da sua preferência!

Como criar CRUD Básico com NestJS, GraphQL e MySQL Luby Software
Como criar CRUD Básico com NestJS, GraphQL e MySQL 3
  1. Levando em consideração que você já saiba como criar um banco de dados, faça os passos descritos na imagem abaixo para criação desse banco de dados no DBeaver!
Como criar CRUD Básico com NestJS, GraphQL e MySQL Luby Software
Como criar CRUD Básico com NestJS, GraphQL e MySQL 4

Configurando o GraphQL

Documentações de referência para projeto CRUD: https://docs.nestjs.com/graphql/quick-start, https://www.npmjs.com/package/graphql, https://www.npmjs.com/package/@nestjs/apollo, https://www.npmjs.com/package/apollo-server-express e https://www.npmjs.com/package/@nestjs/graphql.

  1. Instalação da dependências: yarn add @nestjs/graphql @nestjs/apollo graphql graphql-tools apollo-server-express
  2. Dentro do diretório src, vamos modificar o arquivo app.module.ts novamente, com a nova funcionalidade do GraphQLModule:
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm'
//importações para utilização do graphql
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { join } from 'path';
@Module({
imports: [
TypeOrmModule.forRoot({
type: "mysql",
host: "localhost",
port: 3306,
username: "root",
password: "",
database: "graphql_database",
entities: [
"dist/**/*.entity{.ts,.js}"
],
synchronize: true
}),
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule { }

Adicione GraphQLModule dentro do array de imports: []. Conforme o código supracitado! Assim, vamos utilizar o autoSchemaFile para fazer a geração do arquivo de schema.gql com as tipagens de forma automática e utilizar o servidor do Apollo para utilização do GraphQL.

Criando o Module, Service, Resolver e Entity de Users

  1. Comando para criação do modulo: nest g module user

Dessa forma, a imagem abaixo descreve o que você deve visualizar de saída.

Como criar CRUD Básico com NestJS, GraphQL e MySQL Luby Software
Como criar CRUD Básico com NestJS, GraphQL e MySQL 5

O comando irá instanciar automaticamente o módulo de usuário e criar o arquivo. Assim, o mesmo acontecerá para os próximos passos.

  1. Comando para criação do serviço: nest g s user
  2. Comando para criação do resolver: nest g r user
  3. Vamos criar nosso arquivo de entidade no caminho src/user com o seguinte nome user.entity.ts
Como criar CRUD Básico com NestJS, GraphQL e MySQL Luby Software
Como criar CRUD Básico com NestJS, GraphQL e MySQL 6
  1. Na entidade, vamos especificar todas as colunas que teremos em nossa tabela de users no banco de dados.

Configurando nossa entidade de Usuários

Documentações de referência para projeto CRUD: https://docs.nestjs.com/graphql/resolvers e https://docs.nestjs.com/graphql/cli-plugin.

As entidades se assemelham bastante com a estrutura de migrations. Então, é nesse arquivo que definimos como vai ficar estruturado as colunas da tabela em nosso banco de dados!

  1. Vamos adicionar ao arquivo que criamos na última etapa do tópico anterior (src/user/user.entity.ts), o seguinte trecho de código:
// importações
import { Field, ID, ObjectType } from '@nestjs/graphql';
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@ObjectType() //Informa que é um objeto
@Entity() //Especifica ao código que essa classe se trata de uma entidade
export class User {
@PrimaryGeneratedColumn() // Especifica ao NestJS que a coluna id é uma coluna de chave primaria que é gerada automaticamente
@Field(() => ID) // Informa ao graphql o tipo da coluna
id: string; // tipagem da coluna
@Column()
name: string;
@Column()
email: string;
}
  1. Para não precisar especificar @Field() para colunas de tipos comum e deixar o código mais limpo, podemos utilizar o seguinte trecho de código no arquivo nest-cli.json na raiz do nosso projeto.
{
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"plugins": [
{
"name": "@nestjs/graphql/plugin",
"options": {
"typeFileNameSuffix": [
".input.ts",
".args.ts",
".entity.ts",
".type.ts"
]
}
}
]
}
}

DTO e Validators

Documentação de referência para projeto CRUD: https://docs.nestjs.com/techniques/validation.

  1. Instalação da lib para validação: yarn add class-validator
  2. Instalação da lib para transformação da classe: yarn add class-transformer
  3. Dentro do caminho src/user, crie uma pasta e nomeie como dto e adicione dois arquivos dentro desta pasta chamada createuser.input.ts e update-user.input.ts
  4. Dentro do arquivo create-user.input.ts, adicione o seguinte trecho de código:
// importações
import { InputType } from "@nestjs/graphql";
import { IsEmail, IsNotEmpty, IsString } from "class-validator";
@InputType() //Define que essa classe é do tipo input, que são os valores que serão recebidos pelo endpoint
export class CreateUserInput {
@IsString()// Validação do tipo do input
@IsNotEmpty({ message: "Campo de name obrigatório" })//Validação para não aceitar o valor vazio para chave
name: string; //Tipagem da coluna
@IsEmail()// Validação do tipo do input
@IsNotEmpty({ message: "Campo de email obrigatório" })//Validação para não aceitar o valor vazio para chave
email: string; //Tipagem da coluna
}

Então, dentro do arquivo update-user.input.ts, adicione o seguinte trecho de código:

// importações
import { InputType } from "@nestjs/graphql";
import { IsEmail, IsNotEmpty, IsOptional, IsString } from "class-validator";
@InputType() //Define que essa classe é do tipo input, que são os valores que serão recebidos pelo endpoint
export class UpdateUserInput {
@IsString()// Validação do tipo do input
@IsNotEmpty({ message: "Campo de name obrigatório" })//Validação para não aceitar o valor vazio para chave
@IsOptional()// Define o campo como opcional
name?: string; //Tipagem da coluna
@IsEmail()// Validação do tipo do input
@IsNotEmpty({ message: "Campo de email obrigatório" })//Validação para não aceitar o valor vazio para chave
@IsOptional()// Define o campo como opcional
email?: string; //Tipagem da coluna
}

6. Adicione, no arquivo src/main.ts, o uso global das validações:

import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe()) //Para utilizar as validações globalmente
await app.listen(3000);
}
bootstrap();

Implementando o Service de User

Documentação de referência para projeto CRUD: https://docs.nestjs.com/providers#services

Service é o arquivo responsável por conter todas nossas funções que faram comunicação direta com o banco. Além disso, ele se assemelha muito aos controllers em outros frameworks.

Portanto, vamos modificar o arquivo src/user/user.service.ts com o seguinte trecho de código:

// importações
import { Injectable, InternalServerErrorException, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { CreateUserInput } from './dto/create-user.input';
import { UpdateUserInput } from './dto/update-user.input';
import { User } from './user.entity'
@Injectable() // para fazer injeção de dependências no nestjs
export class UserService {
//injeta o repositório utilizando a entidade de usuário
constructor(
@InjectRepository(User)
private userRepository: Repository<User>
) { }
//método para listagem de usuários
async findAllUsers(): Promise<User[]> {
const users = await this.userRepository.find()
return users
}
//método para trazer um usuário por id
async findUserById(id: string): Promise<User> {
const user = await this.userRepository.findOneBy({ id })
if (!user) {
throw new NotFoundException("Usuário não encontrado")
}
return user
}
//método para criar um usuário
async createUser(data: CreateUserInput): Promise<User> {
const user = this.userRepository.create(data);
const userSaved = await this.userRepository.save(user)
if (!userSaved) {
throw new InternalServerErrorException('Falha na criação do usuário')
}
return userSaved
}
//método para alterar um usuário
async updateUser(id: string, data: UpdateUserInput): Promise<User> {
const user = await this.findUserById(id);
await this.userRepository.update(user, { ...data });
const userUpdated = this.userRepository.create({ ...user, ...data })
return userUpdated;
}
//método para exclusão de um usuário
async deleteUser(id: string): Promise<boolean> {
const user = await this.findUserById(id);
const deleted = await this.userRepository.delete(user);
if (deleted) {
return true;
}
return false;
}
}

Implementando o Resolver de User e importando o TypeORM para o módulo de User

Documentação de referência para projeto CRUD: https://docs.nestjs.com/graphql/resolvers#resolvers

Os Resolvers fornecem instruções para transformar uma operação do GraphQL (@Query @Mutation) em dados. Assim, aqui ficará definido o que uma função recebe e o que ela retorna!

  1. Vamos modificar o arquivo src/user/user.resolver.ts com o seguinte trecho de código:
// importações
import { Args, Mutation, Resolver, Query } from '@nestjs/graphql';
import { CreateUserInput } from './dto/create-user.input';
import { UpdateUserInput } from './dto/update-user.input';
import { User } from './user.entity';
import { UserService } from './user.service';
@Resolver('User')
export class UserResolver {
//Ejetar nosso userService
constructor(private userService: UserService) { }
@Query(() => [User]) //informa ao graphql que esse método vai retornar um array de usuários e que não há modificação do banco com ela
async users(): Promise<User[]> {
const users = await this.userService.findAllUsers()
return users
}
@Query(() => User) //informa ao graphql que esse método vai retornar um usuário em especifico e que não há modificação do banco
async user(@Args('id') id: string): Promise<User> {
const user = await this.userService.findUserById(id)
return user
}
@Mutation(() => User) //informa ao graphql que esse método vai modificar o estado no nosso banco de dados
async createUser(@Args('data') data: CreateUserInput): Promise<User> {
const user = await this.userService.createUser(data)
return user
}
@Mutation(() => User) //informa ao graphql que esse método vai modificar o estado no nosso banco de dados
async updateUser(
@Args('id') id: string,
@Args('data') data: UpdateUserInput
): Promise<User> {
const user = this.userService.updateUser(id, data);
return user;
}
@Mutation(() => Boolean) //informa ao graphql que esse método vai modificar o estado no nosso banco de dados
async deleteUser(
@Args('id') id: string
): Promise<boolean> {
const deleted = await this.userService.deleteUser(id);
return deleted;
}
}

2. Vamos modificar o arquivo src/user/user.module.ts com o seguinte trecho de código:

import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserResolver } from './user.resolver';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';
@Module({
imports: [
TypeOrmModule.forFeature([User])
],
providers: [UserService, UserResolver]
})
export class UserModule { }

Testando nossos endpoints

  1. Comando para execução do servidor: yarn run start:dev

Com isso, a saída deve se apresentar como na imagem abaixo:

Como criar CRUD Básico com NestJS, GraphQL e MySQL Luby Software
Como criar CRUD Básico com NestJS, GraphQL e MySQL 7
  1. Cole o seguinte endereço no seu navegador: http://localhost:3000/graphql

Dessa forma, após colar o endereço supracitado no navegador, a seguinte página deve aparecer:

Como criar CRUD Básico com NestJS, GraphQL e MySQL Luby Software
Como criar CRUD Básico com NestJS, GraphQL e MySQL 8

Esse é o playground do graphql. Ou seja, a ferramenta que auxilia em nossas requisições!

  1. Para utilizar o playground, vamos primeiro fazer uma listagem de todos os usuários! Digite o código abaixo para fazer essa requisição:
query{
users{
id
name
email
}
}

Assim, ao fazer a consulta na aba esquerda, a aba direita da ferramenta deve exibir o seguinte resultado:

Como criar CRUD Básico com NestJS, GraphQL e MySQL Luby Software
Como criar CRUD Básico com NestJS, GraphQL e MySQL 9

Isso acontece porque não temos nenhum usuário registrado.

  1. Para registrar um usuário, crie uma nova aba no playground e cole o seguinte trecho de código.
mutation {
createUser(
data: {
name: "Edith Silva"
email: "edith@email.com"
}
) {
id
name
email
}
}

Dessa forma, a resposta deve aparecer como na imagem abaixo:

Como criar CRUD Básico com NestJS, GraphQL e MySQL Luby Software
Como criar CRUD Básico com NestJS, GraphQL e MySQL 10

Então, à essa altura, já conseguimos listar o usuário criado!

  1. Agora é só você criar mais 3 novas abas, uma para alterar, outra para mostrar pelo ID e outra para excluir, os Body’s estão disponíveis conforme o trecho de código abaixo:
// Em uma nova aba do playground, adicione o body abaixo para fazer uma busca pelo id
query{
user(id: "1"){
id
name
email
}
}
// Em uma nova aba do playground, adicione o body abaixo para fazer uma Alteração
mutation {
updateUser(id: "1", data: { email: "manoel@gmail.com" }) {
id
name
email
}
}
//Em uma nova aba do playground, adicione o body abaixo para fazer uma exclusão
mutation {
deleteUser(id: "1")
}

Veja também:

Entenda gerenciador de pacotes

Uma fração do CRUD

Assim encerramos nossa implementação de um CRUD básico de usuários, utilizando o NestJS, GraphQL e SGBD MySQL. O que foi ensinado nesse artigo é uma pequena fração de tudo que o CRUD essas demais tecnologias podem nos entregar!

Dessa forma, sugiro que a partir daqui, vocês explorem cada vez mais a própria documentação e qualquer dúvida, estou aberto para discussões através do Discord (Manoel Fernandes Neto#5644) ou Linkedin.

Autor: Manoel Fernandes Neto.

[adrotate banner=”5″]

O post Como criar CRUD Básico com NestJS, GraphQL e MySQL apareceu primeiro em Luby Software.

]]>