GITHUB BLOG
Programação Web, o que é?
A Programação Web é a ciência por trás de tudo o que vemos e interagimos na internet. Desde simples páginas estáticas, como Landing Pages, até complexas aplicações dinâmicas, a programação web é o alicerce que sustenta a vasta rede de informações e serviços online que utilizamos diariamente.
Fundamentos da Programação Web
Em sua essência, a Programação Web envolve a criação de páginas, sites e aplicações que são executadas em navegadores web., utilizando uma combinação de HTML (linguagem de marcação), CSS (estilos) e JavaScript (linguagem de programação), os desenvolvedores web constroem interfaces que não apenas são visualmente atraentes, mas também funcionam de maneira eficiente e intuitiva para os usuários.
Ferramentas e Tecnologias Modernas
À medida que a internet evoluiu, também o fez a Programação Web, com o surgimento de novas ferramentas e tecnologias:
-
Frameworks Front-End: Como o React.js, Angular e Vue.js, que simplificam o desenvolvimento de interfaces complexas e interativas.
-
Frameworks Back-End: Como o Node.js, Django e Ruby on Rails, que permitem a criação de aplicações web robustas e escaláveis, gerenciando o lado do servidor e a lógica de negócios.
-
Bancos de Dados: Como MySQL, PostgreSQL e MongoDB, essenciais para armazenar e gerenciar dados em aplicações web.
-
Protocolos e APIs: Como HTTP/HTTPS e RESTful APIs, GraphQL, Web Socket, que facilitam a comunicação entre diferentes sistemas e serviços na web.
Exemplo Prático
Usarei meu projeto gerenciador de hábitos como exemplo. O Front-End foi construído com Next.js que conecta à um REST API em Node.js usando o micro-framework Fastify.
Node.js - Back-End
Primeiro abordarei a parte do Back-End que está disponível publicamente no meu GitHub, o conteúdo mostrado aqui pode ser encontrado nas pastas src/infra/app.ts, src/infra/applications/habits-tracker/routes/users.ts e src/infra/applications/habits-tracker/routes/application.ts.
Para possibilitar a execução de testes end-to-end é necessário separar a implementação das funcionalidades da api da conexão dela com o exterior, para isso eu crio um arquivo chamado app.ts que irá conter as funcionalidades, a conexão com banco de dados e a lógica das regras de negócio. Então crio outro arquivo chamado server.ts que fará a conexão com o exterior atravéz do método listen. Abaixo está o conteúdo do app.ts
Node.js - Realizando as importações necessárias
As importações são essenciais para organizar o código, facilitar a reutilização de componentes e funções, evitar a poluição do arquivo com código em excesso, e garantir uma estrutura escalável de fácil mantenção. Elas ajudam na localização rápida de recursos, melhoram a integração com ferramentas de desenvolvimento e permitem uma gestão eficiente de dependências, contribuindo para um desenvolvimento mais eficiente e organizado.
Node.js - Instanciando o Fastify
Fastify é um framework web para Node.js conhecido por sua velocidade e eficiência. Projetado para lidar com cargas intensivas, oferece alto desempenho com baixo consumo de recursos. Inclui suporte a plugins, validação de entrada, logging integrado e é baseado em TypeScript para desenvolvimento seguro. É uma escolha robusta para construir APIs rápidas e escaláveis.
Saiba mais sobre o framework Configurando um servidor com Fastify. ou consultando sua documentação
Node.js - Configurando o cors
CORS (Cross-Origin Resource Sharing) é uma política de segurança que os navegadores aplicam para controlar como recursos de um site podem ser acessados por outro site. Ela protege contra acesso não autorizado a APIs e informações sensíveis, definindo quais origens podem fazer solicitações e quais métodos HTTP são permitidos. Essa medida ajuda a prevenir ataques e garante um ambiente web mais seguro.
A documentação do MDN oferece mais informações sobre o cors.
Node.js - Adicionando autenticação por JWT
JWT (JSON Web Token) é um formato padrão para transmitir informações entre partes de forma segura como um objeto JSON. Usado principalmente para autenticação, ele consiste em três partes: cabeçalho, carga útil e assinatura. O JWT é gerado pelo servidor ao autenticar um usuário e é enviado de volta ao cliente, que o armazena e o envia em requisições subsequentes para autenticação. Ele é seguro porque é assinado digitalmente e pode conter informações úteis, como identificação de usuário e autorizações.
Node.js - Integrando o plugin de Cookies
Cookies são pequenos arquivos de texto armazenados no navegador do usuário. Eles servem para manter sessões de usuário, armazenar preferências e rastrear informações de navegação. Os cookies podem ser de sessão (temporários) ou persistentes (permanecem até expirarem ou serem excluídos). São importantes para personalizar experiências online, mas levantam questões de segurança e privacidade. Os usuários podem controlar cookies nas configurações do navegador, e há regulamentações como o GDPR que exigem consentimento para o uso de cookies não essenciais.
Node.js - Adicionando os plugins criados por mim para integrar as rotas da aplicação
Rotas em uma API são URLs que definem como os recursos podem ser acessados e manipulados. Cada rota corresponde a um endpoint específico, como /usuarios para listar usuários. Métodos HTTP como GET (para obter dados), POST (para criar), PUT/PATCH (para atualizar) e DELETE (para excluir) são usados para operações sobre esses recursos. As rotas podem incluir parâmetros dinâmicos, como IDs de recursos. É importante documentar e garantir segurança nas rotas, usando práticas como autenticação via tokens JWT.
Node.js - Adicionando um gerenciador de erros
Gerenciar erros em uma API envolve definir padrões claros de resposta para diferentes tipos de problemas, como erros de validação ou problemas de servidor. É essencial usar códigos de status HTTP apropriados e mensagens de erro descritivas para ajudar os desenvolvedores a diagnosticar e corrigir problemas rapidamente. O tratamento de exceções deve ser feito de forma robusta e centralizada, com logging detalhado dos erros para análise posterior. Documentar bem os tipos de erros e como lidar com eles é fundamental para garantir uma API confiável e de fácil uso.
Node.js - Rotas da aplicação
No trecho "adicionando os plugins criados por mim para integrar as rotas da aplicação" há duas conexões com as rotas. O método register do Fastify adiciona um plugin que pode ser customizado por você, neste caso eu criei dois plugins que conectam o framework com as rotas. A seguir veremos o conteúdo desses plugins.
Node.js - Rotas de usuário (plugin "users")
Este plugin contém todas as rotas que tem relação com o usuário, como login, cadastro e autenticação. Como observado há 3 rotas disponíveis: POTS para "/users/register/jwt", POTS para "/users/authenticate/jwt" e GET para "/users". E cada uma possui um controller para gerenciar as requisições direcionadas a ela.
Node.js - Rotas de funcionalidades (plugin "application")
Este plugin contém todas as rotas que tem relação com as funcionalidades principais da aplicação, como criação, listagem, remoção e atualização de entidades. Há várias rotas relacionadas aos hábitos, várias relacionadas aos dias e uma realcionada aos hábitos do dia. Cada uma possui um controller para gerenciar as requisições direcionadas a ela.
Node.js - Controllers
Os controllers são componentes que gerenciam requisições HTTP em uma aplicação, conectando o cliente à lógica de negócio através dos use cases. Eles recebem requisições, chamam os use cases correspondentes para processar os dados e retornam respostas apropriadas para o cliente. Essa separação de responsabilidades ajuda na organização do código, facilitando a manutenção e promovendo uma arquitetura modular e escalável.
Há mais informações sobre os controllers no artigo Node.js: Entendendo Controllers em NestJS, embora tem foco em outro framework, o conceito de controller é o mesmo.
Next.js - Front-End
Agora abordarei a parte do Front-End, mostrando como integrá-lo com as rotas do servidor Node.js que acabamos de conhecer.
A aplicação Front-End possui somente uma rota, porém é altamente interativa e possui diversos componentes do React para manter tal interatividade, por isso passarei brevemente por seu conteúdo, pois já tem muita informação para digerir.
Eu usei algumas ferramentas para me ajudar no desenvolvimento, como o Tailwindcss para estilização, o Tantack Query para gerenciar as requisições ao servidor, e o shadcn/ui para obter componentes genéricos com responsividade e acessibilidade configuradas.
Mais informações sobre o Tailwindcss estão disponíveis em sua documentação. A documentação do Tanstack Query pode te ajudar a entender melhor esta ferramenta. Consulte a documentação do shadcn/ui para saber mais sobre o pacote.
Next.js - Página Home
A página home irá conter todo o conteúdo da aplicação, eu a dividi em três partes: o Header, o DateTrackerComponent, e o Credits
Next.js - Componente dos Dias do Ano
Este componente é responsável por enviar as propriedades para cada um dos quadradinhos da aplicação e por manter toda a lógica de funcionamento da quantidade de dias que deve estar visível, dê uma olhada para entender melhor. O código completo do trecho abaixo está disponível publicamente no meu GitHub em src/components/date-tracker-component/year-days/index.tsx
Next.js - Deixar 'use client' explícito
Por padrão, os componentes do Next.js são renderizados pelo lado do servidor, fazendo que que o conteúdo da página seja estático. Isto é excelente para otimizar a velocidade de carregamento da página, pois o HTML já vem pronto e não precisa ser renderizado em tempo de execução.
Porém para o propósito desta aplicação isso não é útil, pois a proposta dela é de ser interativa e dinâmica, então não pode ser estática. Para tornar uma página interativa no Next.js é necessário que o componente seja renderizado do lado do cliente, não do lado do servidor, para que o HTML seja renderizado em tempo de execução. Por isso deixamos no topo da ágina uma string contendo 'use client', para informar ao Next.js que este componente deve ser renderizado no lado do cliente.
Next.js - Realizar as importações
Elas são necessárias para usar pacotes de terceiros ou outros módulos criados por você, possui outros benefícios explicados anteriormente.
Next.js - Configura o dayjs para trabalhar com o formato UTC
Datas em UTC (Tempo Universal Coordenado) são um padrão global para sincronização de tempo sem um fuso horário específico. São usadas para garantir consistência em sistemas distribuídos ao redor do mundo, evitando problemas com fusos horários diferentes. UTC é preciso e confiável, essencial para registros precisos em sistemas críticos. Na programação, é comum converter UTC para o fuso horário local para exibição ao usuário final, mantendo a consistência global.
Next.js - Ref do scroll e dateRange
A ref do scroll é obtida à partir do Hook useRef do React e será usado para navegar até o fim do scroll assim que o componente carregar, a fim de enviar o usuário para a data mais atual desde o começo.
O dateRange usa o Hook useMemo do React e seu objetivo é calcular a data desde o início do ano atual até a data de hoje, porém a data inicial deve ser num Domingo e se a distância entre a data atual e a data de hoje forem menor do que 18 semanas, ele irá ultrapassar o início do ano buscando datas do ano anterior até que haja pelo menos 18 semanas de diferença e o dia inicial seja Domingo.
Next.js - Busca os Dias com Tanstack Query
Realiza a requisição para o servidor buscando e salvando em cache todos os dias criados pelo usuário logado
Next.js - yearDays
Busca todos os dias do intervalo calculado pelo dateRange e verifica quais dias desse intervalo estão na mesma data que os dias buscados no servidor e retorna um objeto de formato padrão.
Next.js - Lógica do Ref do scroll
Implementa a lógica do Ref do scroll pra que o usuário seja levado até a data mais recente desde o início.
Next.js - Função handleYearDayState
Cria uma função com o Hook useCallback do React que tem o objetivo de obter a porcentagem de tarefas do dia completas em relação ao total de tarefas programadas para aquele dia. Depois retorna um número de 0 à 5 onde 0 representa que nenhuma tarefa foi cumprida e 5 representa que todas as tarefas foram cumpridas.
Next.js - Retorno JSX do componente
Por fim, retorna o JSX para renderizar o componente, que passa a scroll ref para o compoenente de scroll e faz um loop percorrendo todos os dias do período calculados pelo yearDays e retornando o componente "YearDay", responsável por renderizar cada quadradinho que representa um dia, passando o resultado da função handleYearDayState como parâmetro, que determinará a cor do quadrado .
O que você aprendeu?
Com isso você teve uma base sólida sobre os Fundamentos da Programação Web, com exemplos de Back-End usando Node.js e Front-End usando Next.js.
Este conteúdo foi útil? Deixe seu comentário.