Passar do frontend para o backend não é só mudar de linguagem ou framework; é mudar de perspectiva. Se no front eu estava preocupado com a cor do botão e a experiência de quem clica, no backend eu virei o cara da logística.
Esta semana foi sobre entender como o dado viaja, onde ele para e como evitar que ele fique preso em filas desnecessárias.
O Pátio de Carga: Backend como Logística
Moro em Cubatão, e aqui o Porto de Santos é a referência visual de tudo. O backend é exatamente como a área de retroporto. O usuário vê o navio chegando (a interface), mas o que faz a coisa funcionar é o pátio organizado atrás, onde ninguém entra sem autorização e cada contêiner tem seu lugar.
O Node.js é o JavaScript que saiu da gaiola do navegador. Ele não está mais lá só para validar formulário ou animar menu. Ele está comandando o tráfego. Usar Express para isso deixou claro o fluxo que eu chamo de "Garçom e Cozinha":
| Papel | Função Real | Analogia do Restaurante |
|---|---|---|
| Request | O pedido que chega | O cliente chamando o garçom |
| Route | O caminho do pedido | O garçom levando o bloco de notas |
| Handler | A lógica de preparo | O cozinheiro executando a receita |
| Response | A entrega do dado | O prato chegando na mesa |
Se a rota está errada, o garçom se perde. Se o handler é lento, a cozinha trava. E o pior: o cliente fica esperando sem saber o que aconteceu.
O Gargalo do Await Sequencial
Entender o fluxo foi a parte fácil. O problema começou quando precisei buscar dados de três lugares diferentes. No começo, eu fiz o que parecia óbvio: coloquei um await em cima do outro.
// O erro clássico do iniciante
const usuario = await db.getUsuario(id);
const posts = await db.getPosts(id);
const fotos = await db.getFotos(id);
Eu achava que estava sendo organizado. Na verdade, eu estava criando um sistema de fast-food onde o atendente só anota o pedido da bebida depois que o sanduíche fica pronto, e só pede a batata depois que a bebida é servida. É burrice logística.
O await trava a linha do tempo daquela função. Se cada chamada demora 200ms, eu gastei 600ms em algo que poderia ser resolvido na metade do tempo.
Resolvendo o Fluxo com Promise.all
A ficha caiu quando percebi que o db.getPosts não depende do resultado do db.getFotos. Eles podem — e devem — ser despachados ao mesmo tempo.
A solução é o Promise.all(). É como se eu desse três ordens simultâneas para a cozinha e só esperasse o momento em que a bandeja completa estivesse pronta para ser entregue.
// O jeito inteligente (Logística eficiente)
const [usuario, posts, fotos] = await Promise.all([
db.getUsuario(id),
db.getPosts(id),
db.getFotos(id)
]);
Aqui, o tempo total de espera é apenas o da função mais lenta, não a soma de todas. No mundo real do backend, 400ms de economia é a diferença entre um sistema que escala e um que derruba o servidor no primeiro pico de acesso.
O que fica
O backend não aceita desaforo. Se você não entende como o tempo de execução funciona, você vai construir sistemas lentos achando que o problema é o banco de dados ou a internet do usuário.
Descobri que o meu papel como dev backend é ser menos "artista" e mais "engenheiro de tráfego". O código bonito é o código que não deixa o dado parado no pátio esperando uma autorização que ele nem precisava ter.
É isso.