Frontend pro Tabnews #1 | Consumindo uma API no Lado do Cliente
No final do mês passado eu decidi dar uma pequena pausa numa web app1 que eu estava fazendo pra aprender um pouco mais de SQL, Go e HTMX – e pra me divertir, principalmente –, então decidi voltar a minha atenção pro frontend mais uma vez, dediquei boa parte do meu tempo nesses últimos anos melhorando minhas skills no backend e em ferramentais pra Linux e coisas assim (Regex, AWK, Bash… você sabe, as paradas divertidas underhated do mundo Linux).
O que me motivou a voltar às minhas origens foi o fato de eu ter decido usar, justamente, HTMX pra fazer a comunicação entre o frontend da minha aplicação e o backend. E realmente funcionou super bem, tudo pareceu idiomático e natural, me economizou um bom tempo que gastaria escrevendo Javascript + AJAX, super recomendo dar uma chance pra essa biblioteca. Agora que entendi o hype em volta dessa nova ferramenta, fui explorar seu potencial e me atualizar um pouco no front pra não ficar tão pra trás – Bem, pelo visto eu tinha realmente perdido muita coisa, agora o CSS finalmente tem regras pra animar elementos durante o scroll da página ou pra quando eles ficam visíveis pro usuário, e também suporta a sintaxe de nesting, similar a um SASS ou um Less da vida (nos próximos posts da série eu vou comentar mais sobre).
Coincidentemente, um amigo meio me apresentou o fórum Tabnews do Filipe Deschamps. Não conhecia direito essa plataforma, então criei uma conta, participei em algumas threads e fiz uma pequena publicaçãozinha pra engajar, depois caí num vídeo que o Filipe dá mais detalhes, e lá descobri que ela tem uma API que me dá acesso a todos os posts, comentários e dados de usuário registrados no banco da aplicação, o que é dahora da parte deles (btw, a plataforma toda é open source).
Daí pintou a ideia que tu leu no título já: dado o, relativamente, grande
ecossistema de bibliotecas em Javascript e CSS que estão disponíveis pra serem
consumidas no frontend de uma aplicação via CDN, o quão longe é possível ir só
com um único arquivo .html
? Com certeza dá pra ir muito mais longe do que
imaginei quando comecei e é provável que dê pra ir mais ainda, considerando o
meme de ter mais bibliotecas em Javascript do que pessoas na Índia, mas mesmo
assim, quero compartilhar umas coisas que aprendi nessa brincadeira – no final
do dia eu sou só mais um cara curioso que também tá começando nessa área de
desenvolvimento.
Puxando Informações de uma API com Javascript Puro
O primeiro, e mais importante, problema que preciso resolver pra começar esse
projeto é dar um jeito de, justamente, puxar as informações da API do Tabnews.
Mas esse é o mais fácil, é possível pedir coisa pra um servidor usando só o
Javascript no frontend sem problema nenhum com AJAX. O jeito que se usa as
ferramentas pra isso é meio complicado, mas nada impossível; E vale a pena
brincar um pouco com isso, eu vou abrir a página about:blank
do Firefox aqui
e digitar o seguinte no console:
1//nota: Esse trecho cria uma tag <main id="app"> e coloca no <body>
2
3const $app = document.createElement("main");
4
5$app.setAttribute("id", "app");
6$app.setAttribute("style", "background:black; color:lime;");
7
8document.body.appendChild($app);
9
10
11//nota: É aqui que a parte que importa começa
12
13const API_ADDR = "https://qlrcfuxdfgwxkqe.free.beeceptor.com";
14const xhr = new XMLHttpRequest();
15
16xhr.onload = () => {
17 const res = xhr.response;
18 const $target = document.querySelector("#app");
19
20 $target.innerHTML = res;
21};
22
23xhr.open("GET", API_ADDR);
24xhr.send();
Essa URL, em API_ADDR
, é uma pequena API de teste que eu fiz rapidinho no
site Beecepter2, que achei por ai. Pode ser útil pra
ti que quer fazer alguns testes desse mesmo tipo, só recomendo que use
letras geradas aleatoriamente por algum gerador de senha, ou coisa assim, pros
nomes das suas APIs no plano gratuito. Enfim…
O detalhe sobre esse código é que, por eu estar em about:blank
, eu decidi
criar um elemento <main id="app">
e inserir ele na página com Javascript por
um ou dois motivos. O primeiro é que mais ou menos assim que bibliotecas como o
React funcionam por baixo – por isso as páginas quebram quando o Javascript
está desativado –, então achei que seria legal comentar sobre aqui, já que
isso vai ser relevante mais pra frente. E o segundo motivo é que eu posso
aproveitar isso pra mudar o CSS dessa tag pra ficar mais visível pra mim que
usa a extensão Dark Reader pra ter o tema escuro na maioria dos sites.
HTMX e suas Conveniências
Ok, mas essa minha solução com AJAX só vai me dar problema, vou ter muito
Javascript num arquivo .html
, não me parece certo. Felizmente a biblioteca
HTMX faz justamente isso pra mim, e também no frontend como eu estou fazendo
agora. Se você já ouviu falar de HTMX e não sabia o que ele era exatamente,
agora você sabe: um conjunto de funções e scripts que facilita puxar
informações de alguma API via AJAX e inserir na sua página. Só.
Dessa vez, eu vou criar um arquivo em HTML, digamos… htmx-demo.html
, e vou
abrir esse arquivo com o Firefox como você faria com qualquer documento em
HTML. Dentro desse arquivo, eu vou importar a biblioteca em Javascript do HTMX
via CDN, depois eu vou criar o meu <main id="app">
do jeito que
mandei o Javascript criar no código anterior, mas eu vou adicionar alguns
atributos diferentes, atributos esses que o HTMX vai ler e interpretar pra
fazer o que eu quero:
1<!DOCTYPE html>
2<html lang="en">
3 <head>
4 <script src="https://unpkg.com/htmx.org"></script>
5 </head>
6 <body>
7
8 <main
9 hx-get="https://qlrcfuxdfgwxkqe.free.beeceptor.com"
10 hx-target="this"
11 hx-trigger="load"
12 id="app"
13 style="background:black; color:lime;"
14 ></main>
15
16 </body>
17</html>
Quando eu atualizar essa página no navegador, eu devo esperar o mesmo resultado
que tive com script que rodei na about:blank
. E eu acho que só esse código já
é bem direto ao ponto, esse elemento main#app
vai fazer uma aquisição GET
pra aquela API lá que eu tinha feito, e essa aquisição só será feita quando ele
for carregado no meu navegador – se liga no hx-trigger
. E esse hx-target
será o elemento que o HTMX vai usar pra colocar o que a API respondeu, no caso,
o this
vai apontar para o próprio elemento que tá fazendo a aquisição.
Mas assim, isso é o hello world do HTMX, dá pra você ir bem mais longe que
isso. É possível usar um query selector pra apontar pra outro elemento, como
#ola-mundo
no target, ou até selecionar o elemento mais próximo com
next .ola-mundo
; ainda dá pra especificar como ele deve inserir a resposta na
página, como dizer se a resposta deve substituir o target, se deve ser
inserida depois/antes, ou no final/começo dentro dele, se ele deve ser
substituído pela resposta, e assim vai. Existem dúzias de eventos, opções e
funções que você deve usar e abusar na sua aplicação, e é assim que você
consegue o mesmo nível de reatividade que o React proporciona sem depender
dessa biblioteca! Enfim, leia as documentações pra saber mais, não é tão
complicado entender como ela funciona.
Se você der uma passada de olho nas documentações, não fica difícil de sair de
lá já com algumas ideias de como implementar features como o scroll infinito
com o evento intersects
que dispara quando o elemento aparece na view
port3, atualização de estado com eventos customizados4 ou update de
informações em tempo real5.
Sei que pareço um fanático a essa altura, mas fazer o que se a biblioteca é boa, né? Além disso, entender como ela funciona vai ser importante pra entender a lógica de templates que usei pro projeto, então presta atenção pra não se perder.
Concluindo
Ok, acho que esse post vai ficar longo demais então vou dividir ele em posts menores em uma série mais fácil de consumir. Ainda quero falar um pouco sobre CSS, Bootstrap, Tailwind e SASS, depois quero abordar alguns problemas que passei durante o desenvolvimento e, finalmente, se eu tivesse a paciência pra fazer esse projeto de novo como eu faria usando uma stack mais “séria”.
No mais, é isso. Espero que esse post tenha, ao menos, te atualizado um pouco na área do frontend, saber que o HTMX existe pode ser uma mão na roda, principalmente pra projetos pequenos que você precisa de uma interface meia boca e não quer perder muito tempo com AJAX pra puxar ou inserir dados no seu banco.
É até legal escrever um artigo sobre isso sabendo que eu odiava a ideia do HTMX antes de experimentar. No próximo post eu vou falar sobre o único “problema” que torna o HTMX alvo de crítica – vou falar sobre essa crítica também – e como dar uma volta nesse problema com plugins (sim, HTMX tem suporte a plugins também).
Se tiver alguma dúvida com os exemplos anteriores, não deixe de comentar abaixo e compartilhe com seus amigos se tu achou esse post relevante. Obrigado pela leitura! ❤️
O projeto está longe de estar completo, mas se tiver curiosidade ta aqui o link para o repositório. Não tem nenhuma documentação, mas acho que da pra deduzir como rodar e experimentar essa aplicação passando o olho no
docker-compose.yml
e rodando./insert_dummy.py --help
pra entender o que esse script faz (você vai precisar baixar as dependências dele antes, lógico). ↩︎Não sei exatamente por quanto tempo ela vai ficar de pé, mas sinta-se livre pra usar ela nos seus experimentos caso esteja curioso. ↩︎
Esse evento pode ser disparado sempre que o usuário scrollar a tela o suficiente pra exibir um elemento vazio que faz essa aquisição, dá pra usar o
hx-indicator
pra ter uma animaçãozinha de carregamento e você pode usar variáveis globais do próprio Javascript pra por na aquisição – por exemplo, “puxe a página 2 do banco”, depois de scrollar até o final mais uma vez, “puxe a página 3 do banco” e assim vai. ↩︎O usuário pode clicar em um produto na UI pra por no carrinho, então esse clique pode disparar múltiplos eventos que podem atualizar o estado do card em que o usuário clicou, mudar o ícone de carrinho vazio na barra de tarefas pra um ícone de carrinho cheio ou atualizar a lista de carrinhos no menu do usuário, por exemplo. ↩︎
Isso talvez seja útil em uma aplicação de chat, ou num clone de e-mail, onde a página precisa ficar de tempos em tempos puxando dados do seu backend pra manter o usuário a par do que está sendo enviado/recebido. ↩︎
#Programming #Learning #Htmx #Html #Series #Tabnews #Frontend
comments powered by Disqus