Olá, aluno(a)! O objetivo da aula de hoje é conhecer alguns recursos utilizados no desenvolvimento de software para front-end moderno, que são os Frameworks e Requisições assíncronas. Primeiramente, você verá o conceito sobre Framework, uma estrutura de software que fornece uma base para o desenvolvimento de aplicações. Ele inclui e absorve vários detalhes do desenvolvimento básico que se faz hoje, além de oferecer funcionalidades prontas para serem utilizadas, o que faz com que você tenha muito mais produtividade no desenvolvimento de novos códigos e novos projetos.
Esses chamados frameworks têm aplicabilidade em diversos setores: como web, mobile, desktop e até mesmo em inteligência artificial. No momento, a tendência de frameworks, principalmente naqueles baseados em JavaScript, incluem a utilização de tecnologias como React, Angular e VueJS.
Outro recurso que você conhecerá nesta lição são as requisições assíncronas, que também podem ser chamadas de AJAX, estas permitem que uma página da web atualize partes específicas sem recarregar a página inteira. Isso é especialmente útil para melhorar a experiência do usuário, pois as requisições assíncronas não interrompem o fluxo de trabalho do usuário. Elas também são amplamente utilizadas em aplicações web modernas, como Gmail e Google Maps. Elas também são implementadas por meio de tecnologias como XMLHttpRequest, Fetch e Axios.
Portanto, prepare-se para conhecer os conceitos e aplicações dos recursos dos frameworks e requisições assíncronas!
Antes do surgimento de frameworks, para o desenvolvimento front-end, as pessoas desenvolvedoras precisavam escrever código JavaScript manualmente para manipular o DOM (Document Object Model) e renderizar componentes da interface do usuário. O problema disso era a questão da produtividade e complexidade de tais tarefas, ou seja, para uma interface ficar pronta levaria mais tempo e, consequentemente, também seria mais caro.
Com isso, você já pode identificar que frameworks como React ajudam a solucionar o problema de desenvolvimento de interfaces do usuário que são complexas e dinâmicas em aplicações para web. Pois bem, com React (framework de JavaScript de código aberto, criado pelo Facebook, lançado em 2013), as pessoas desenvolvedoras podem criar componentes inteiros reutilizáveis e declarativos que descrevem como a interface do usuário deve ser atualizada em respostas às mudanças de estado ou de dados.
Todo esse aparato torna o desenvolvimento de interfaces de usuário mais rápido, mais fácil de manter e menos propenso a erros. Além disso, também pode-se trabalhar com suporte a recursos como a renderização no lado do servidor e a construção de aplicativos móveis nativos, tornando o React e React-Native uma opção poderosa para desenvolvimento de aplicativos multiplataforma.
Apresentamos a você um case fictício, da empresa ASDF Inc., que atua na área de tecnologia, mais especificamente no desenvolvimento de sistemas web. No momento atual ela está desenvolvendo um aplicativo web bastante complexo, que exige muitas requisições para buscar e exibir dados atualizados em tempo real. No entanto, ao mesmo tempo que funcionalidades são incrementadas, o sistema tem ganhado lentidão e pouca responsividade, porque todas estas requisições citadas são realizadas de forma síncrona, gerando em uma experiência do usuário negativa.
A decisão tomada pela equipe de desenvolvimento não poderia ser diferente: implementar requisições assíncronas para melhorar o desempenho e a responsividade do aplicativo. Foi utilizado o framework React para criar os componentes reutilizáveis e para gerenciar as requisições assíncronas. A equipe usou o Redux – um gerenciador de estado previsível para aplicativos JavaScript, que permite que as informações sejam armazenadas em um local centralizado e acessadas por qualquer componente que precise deles.
Com essas implementações, o aplicativo em questão ficou mais rápido e responsivo, o que resultou em uma experiência do usuário significativamente melhor. Os usuários agora podem ver as atualizações em tempo real, sem precisar esperar o carregamento da página por completo além de deixar o código mais organizado e fácil de entender, tornando o processo de desenvolvimento mais eficiente e menos propenso a erros.
Acho que a pergunta que sempre que é feita e demora um pouco para ser respondida é: o que é um framework? E por que digo isso? Porque você citar quais são os frameworks ou usá-los é uma coisa, mas quando você precisa conceitualizar o que é um framework geralmente o que ocorre é uma confusão com a definição. Por isso, mostraremos alguns fatos que podem lhe ajudar a entender este conceito, visto que a pergunta “qual a diferença entre um framework e uma biblioteca?” é comum aparecer em algum momento de seu estudo.
Gomes (2013 apud PRESSMAN, 2011) define framework como uma “mini” arquitetura reusável, que fornece a estrutura e comportamentos genéricos para uma família de abstrações de software dentro de um contexto. Contexto esse que especifica sua colaboração e o uso em um determinado domínio.
Gomes (2013 apud MATSUMOTO et al., 2011) afirmam que frameworks resolvem um conjunto particular de problemas que são adaptados para contextos específicos e podem prover um projeto otimizado para a aplicação, ou seja, o framework provê uma estrutura onde ao se trabalhar com ele, você precisará se preocupar mais com o negócio do seu sistema do que com regras e padrões para autenticação, envio de formulários, persistência em banco de dados etc. Ademais, por ser “uma família de abstrações de software” Gomes (2013 apud MATSUMOTO et al., 2011) ainda diferem framework de bibliotecas, pois afirmam que componentes de bibliotecas podem ser conectados na estrutura de um framework e são subclasses concretas que fazem o trabalho real, ou seja, bibliotecas e/ou componentes já possuem um objetivo específico e imutável, por exemplo: uma biblioteca para formatação de datas trabalha somente com isso e incluí-la em seu projeto tem o objetivo de formatar apenas datas, ou seja, não é adaptável para outra situação. Já o framework é mais genérico, de forma que você o adapta para o contexto ou negócio que desejar.
No entanto, o que dizer sobre os tipos de frameworks? Pois bem, temos frameworks chamados fullstack que resolvem toda a arquitetura de seu sistema, desde conexão com banco de dados, regras de negócio, conexão com APIs externas, envio e recebimento de dados para as Views e também a criação e manutenção delas. Com ele basicamente seu software se torna um subsistema dentro do framework onde você tem disponível uma grande lista de funcionalidades para utilização em seu projeto.
Obviamente, se temos um que resolve todas as situações, também temos aquele framework de back-end que trata apenas de situações que ocorrem no back-end, como as já citadas, como autenticação, conexão com banco de dados e conexão com APIs externas. Temos também o que mais nos interessa nesta lição, que são os frameworks front-end, que possuem em uma maioria base na linguagem JavaScript e tomam conta do mercado. O mercado desses frameworks é avassalador e não para. Brincamos, muitas vezes, que, a cada parágrafo escrito desta lição, mais um framework javaScript foi criado no mercado. É claro que existem também aqueles que já passaram da fase de novidade e se consolidaram no mercado. Citaremos alguns aqui para que você saiba:
É o “queridinho” do mercado, sendo ele criado pelo Facebook. Ele serve como base para o React Native, principal framework de desenvolvimento de aplicativos multiplataforma (híbridos) para dispositivos móveis. Sua documentação encontra-se disponível em https://react.dev/.
Um dos primeiros, senão o primeiro, framework criado pela google e que trouxe todo um mundo de novidades e deu notoriedade ao front-end. Com a criação, não seria mais somente as “telas” do sistema, e passou a ter procedimentos e comportamentos nele também. Sua documentação encontra-se disponível em https://angular.io/.
Poderia dizer que esse completa a tríade de frameworks mais usados hoje, ele foi criado por um ex-funcionário da google e ganhou notoriedade após ter sido utilizado pelo criador de um outro framework, chamado Laravel (fullstack). Tal descobrimento pode ser visto neste breve documentário sobre sua origem https://www.youtube.com/watch?v=OrxmtDw4pVI, com legendas em português. Sua documentação encontra-se disponível em https://vuejs.org/.
Existem várias vantagens em usar um framework, ele irá lhe proporcionar uma alta qualidade nos projetos, pois já possuem uma grande experiência e testes pelas mãos de quem o projetaram, eles lhe ajudam no quesito produtividade, pois ao invés de pensar e implementar uma séries de recursos básicos a todos os projetos, você utilizando de um framework já vai direto para o problema e/ou situação que seu novo projeto requer, ou seja, a regra de negócio. Entre outras coisas podemos atestar que os frameworks são seguros, vez que são testados por toda uma série de profissionais que o construíram e também pela comunidade que os usa. Eles também otimizam o tempo – como já foi dito – e, principalmente, em sua maioria, tem uma curva de aprendizado pequena, ou seja, são fáceis de manusear, com documentações completas e com exemplos de uso.
Antes de falar sobre o que são as requisições assíncronas, é importante você considerar entender seu contrário, ou seja, o que são as requisições síncronas. Então vamos lá! Segundo MDN Web Docs (2023), normalmente, o código de um programa é executado de forma direta, com uma coisa acontecendo por vez. Se uma função depende de outra função, ela tem que esperar o retorno do resultado e, até que isso aconteça, o programa inteiro praticamente para de funcionar na perspectiva do usuário.
Em outras palavras, quando se utiliza uma requisição síncrona, o processo fica bloqueado, aguardando a resposta do servidor. Exemplificando: no seu dia a dia, seriam as requisições que seu navegador aguarda até o término do processamento do servidor para continuar a executar o código JavaScript, bloqueando assim a sua execução até que a resposta do servidor seja recebida. Um bom designer neste momento, coloca para você um belo loading na tela com alguma porcentagem – ou não – no formato de círculo ou com aquela famosa “barrinha” de progresso, o que, de qualquer forma, não muda o formato de requisição. Em resumo, seu navegador ficará bloqueado até que uma resposta venha do servidor ou de uma API de terceiros.
Agora que você já sabe como funciona uma requisição síncrona, explicaremos como é o funcionamento de uma requisição assíncrona onde você precisa entender que um modelo assíncrono permite que várias coisas aconteçam ao mesmo tempo. Quando você inicia uma ação, seu programa continua em execução. Quando a ação termina, o programa é informado e tem acesso ao resultado (por exemplo, os dados lidos do disco). Em comparação com a requisição síncrona que bloqueia o site até que obtenha a resposta do servidor, a requisição assíncrona, então, não espera a resposta do navegador e segue com a sua execução, quando ele obtiver a resposta ele fornece um feedback ao usuário através de dados que foram solicitados ou através de notificações, tais como e-mails ou alertas na tela informando, por exemplo, “A importação foi realizada com sucesso”.
Imagine um software que tenha a funcionalidade de importar usuários através de planilhas do Excel. Se você importar 10 usuários e o sistema ficar com aquele “Carregando…” por cinco ou dez segundos, é uma coisa, mas imagine se precisar de importar 1000 usuários. Quanto tempo o sistema – ou a pessoa que está aguardando esse carregamento – é capaz de esperar este loading? É neste momento que entra a requisição assíncrona!
Com esse tipo de requisição, nessa situação de importar 1000 usuários, o sistema fornece um feedback avisando que o upload está sendo realizado e nos libera para fazer outras coisas no software. Quando o servidor terminar com a importação, ele me mostra um “balão” verde no canto direito da tela, “A importação dos 1000 usuários foi realizada com sucesso”. A partir disso, volto na tela dos usuários e já os vejo listados como cadastrados. Muito melhor, não é mesmo? Por isso, a principal vantagem de usar requisições assíncronas é uma melhora no uso do servidor, através de forma mais otimizada e fluida, proporcionando uma melhor experiência ao usuário, que não ficará “preso” enquanto o servidor se encarrega de fazer o serviço.
Utilizar uma requisição síncrona ainda tem um grande problema dos servidores que são os chamados timeouts (código para por excesso de tempo), normalmente pré-configurados com valores de segurança os navegadores “quebram” com muito tempo de espera, o que torna requisições síncronas ainda mais complicadas de se usar, pois imagine que você ficou dois minutos esperando por uma importação e recebe o retorno de erro por excesso de tempo. Situação nada agradável, não é mesmo? Essa situação é completamente abstraída com a utilização de requisições assíncronas, até porque em grandes lotes de trabalho ainda se pode contar com mais uma ferramenta chamada fila de processos.
Como estou falando praticamente de JavaScript nesta lição e ao longo desta disciplina, cabe agora explicar como é o funcionamento das requisições assíncronas nesta tecnologia. A principal forma de lidar com esse processamento assíncrono é através da função async/await que foi introduzida na versão ECMAScript 2017 (ES8) do JavaScript. A função foi criada como uma alternativa para lidar com código assíncrono de forma mais clara e legível, e permite que o código assíncrono seja escrito de forma síncrona sem a necessidade de encadeamento de callbacks ou tratamento complexo de erros com promisses. A palavra “async” é usada para definir uma função assíncrona, enquanto o “await” é usado para aguardar a conclusão de uma operação assíncrona, sem bloquear a execução do restante do código.
Com relação à aplicação de uma requisição assíncrona bem como a utilização de um framework (React), acompanhe a Figura 1 a seguir:
Neste exemplo, a função fetchData() utiliza as palavras-chave async/await para fazer uma requisição assíncrona à API https://jsonplaceholder.typicode.com/todos/1 e obter um objeto JSON com os dados. Em seguida, os dados são armazenados no estado data por meio da função setData(). A função useEffect() é utilizada para disparar a execução de fetchData() assim que o componente é montado. O retorno da função ExemploAssincrono() é um componente que exibe os dados retornados pela API, caso eles estejam disponíveis, ou caso contrário, a mensagem Loading…
GOMES, F. Zend Framework componentes poderosos para PHP. 2. São Paulo: Editora Novatec, 2013.
MATSUMOTO, P. M. et al. AOM Metadata Extension Points. In: 18th Conference on Pattern Languages of Programs (PLoP). Portland, Oregon, 2011. 16 p.
MDN web docs. Conceitos gerais de programação assíncrona. Disponível em: https://developer.mozilla.org/pt-BR/docs/conflicting/Learn/JavaScript/Asynchronous/Introducing. Acesso em 17 de abr. 2023
PRESSMAN, R. S. Engenharia de software: uma abordagem profissional. 7. ed. Porto Alegre: AMGH, 2011.