Executando verificação de segurança...
3

O Problema do Node (e do Bun) & Como Deveria Ser o JavaScript no Back-End

Uma breve contexto do JavaScript

O JavaScript, a língua franca da Web, passou por uma grande transformação em relação à sua função inicial - adicionar interatividade à páginas web, para ser usado para consturir virtualmente qualquer aplicação.

De fato, a evolução do JavaScript tem sido profunda, graças aos esforços colossais de gigantes da tecnologia como Mozilla, Google, Microsoft e Apple que otimizaram e refinaram incansavelmente suas implementações, bem como aos meticulosos processos de padronização e que envolveram centanas de organizações e milhares de especialistas. Hoje, o JavaScript, pode ser considerado por diversas medidas objetivas, como uma das melhores linguagens de script disponíveis, tanto em termos de implementação como de especificação.

Ainda assim é importante destacar que o JavaScript é uma linguagem de script, sendo desenvolvida única e exclusivamente com o objetivo de automatizar, gerir e manipular 'coisas' dentro no navegador. Sendo projetada para a execução e integração rápida em um hospedeiro (o navegador) e ser uma sandbox. O JavaScript foi criado para não interegir com o sistema operacional, por exemplo, o que é essencial para criar aplicações.

Esta decisão fundamental significa que a criação de aplicações apenas com JavaScript necessita de uma "gambiarra". A mais famosa é de longe o Node, um programa em C++ que faz a conexão entre o V8 (a caixa-de-areia que executa sua aplicação em JavaScript) com o mundo exterior. Agora surgiu o Bun, mas não se enganem, é apenas uma 'engenhoca' mais elaborada, que tem como propósito, corrigir um 'problema' que é deliberamente uma decisão de projeto da linguagem, o JavaScript não foi feito para criar aplicações!!! E muitos vão teimar em não concordar com isto, mas é uma questão muito simples, basta ler a especificação.

Um fato muito interessante é que apesar disso, o Node é uma ferramenta execelente para criar (certos tipos) de aplicações e o Bun provavlemente vai ser ainda melhor. E isso levanta muitas perguntas interessantes.

Todavia, antes se torna fundamental distuinguir entre aplicações e scripts:

Script na sua essência têm uma unica função, diz respeito à escrita de pequenas rotinas para automatizar tarefas, transformar dados ou extender e controlar outros softwares. Normalmente são rotinas curtas, escritas em um único arquivo e têm toda a entrada necessária no ínicio do processo. Executam até produzir uma única saida e são finalizados. É um fluxo quasi-sequencial. Envolve frequentemente a interação direta com uma 'aplicação hospedeira'. Quase sempre é interpretado pois são usados justamente para ganhos de flexibilidade e produtividade.

Aplicações são software autónomos que interagem diretamente com o mundo real, executando em loop, aguardando por novas entradas de forma constante e produzindo diversas saídas. São verdadeiros emaranhados de chamadas (não importa quão bem projetados) espalhados por diversos arquivos. Frequentemente envolvem processos complexos e abrangentes de design, codificação, build e debug. São destinados a executar um grande conjunto de tarefas de maneira coesa, estruturada e organizada de maneira ininterrupta.

Todo o poder de JavaScript no Backend

(menos) Java

O Java é frequentemente considerado como uma das linguagens de desenvolvimento de aplicativos mais bem-sucedidas, é tão bem sucedido que o nome JavaScript foi propositalmente escolhido para surfar em sua popularidade.

Sua poderosa máquina-virtual, extensa biblioteca padrão, natureza estaticamente tipada com checagens em tempo de compilação e a adoção intrisíca da melhores práticas da orientação a objetos, dão ao Java uma abordagem estruturada para o desenvolvimento de aplicativos, permitindo a construção de sistemas complexos e de grande escala com requisitos rigorosos de confiabilidade e desempenho. Por outro lado, o JavaScript foi concebido como uma linguagem de script.

Muitas aplicações que utilizam Node/Typescript/Prisma parecem adotar padrões de design, abordagens de arquitetura e rationales que são típicos do Java, ou qualquer outra linguagem focada no desenvolvimento de aplicações como C#.

(mais) Script

A utilização ideal do JavaScript no desenvolvimento de back-end da Web não está em replicar a funcionalidade de linguagens feitas para desenvolver aplicativos complexos, mas em criar scripts e automatizar as ferramentas que alimentam a Web, como por exemplo Nginx e Postgres.

Em vez de trazer nosso servidor Web e dados para dentro do JavaScript, como paradigma do desenvolvimento de aplicações e frequentemente feito no Node, levar o JavaScript diretamente para nosso servidor (Nginx) e dados (Postgres) é uma abordagem muito mais sensata e fiel ao seu próposito como linguagem de script. Essa abordagem perrmite a extensão dessas ferramentas com maestria através da flexibilidade e perfomance que apenas o JavaScript é capaz de oferecer, enquanto aproveita toda a velocidade, robustez e eficiência das ferramentas que estão sendo controladas.

Extendendo o banco de dados com plv8:

O plv8 fornece um ambiente de execução para JavaScript dentro do PostgreSQL, permitindo a execução de código JavaScript diretamente dentro do banco de dados. Isso oferece a possibilidade de definir e impor regras de negócios no nível do banco de dados, garantindo consistência e integridade dos dados. Tradicionalmente isso sempre foi feito usando Procedural SQL (e provavelmente por isso também, bastante evitado por muitos desenvolvedores) mas por que não aproveitar todas as vantagens do js?

CREATE OR REPLACE FUNCTION valida_usuario()
  RETURNS TRIGGER AS $$
    const novoUsuario = NEW.nome_usuario;
    const email = NEW.email;

    if (novoUsuario.length < 5 || !email.includes('@')) {
      plv8.elog(ERROR, 'Usuário inválido!');
      return null; 
    }
    
    return NEW;
$$ LANGUAGE plv8;

Este não é um artigo sobre a programação de banco de dados (quem sabe em outro artigo), mas segundo a documentação do próprio Prisma:

"There are two schools of thought about performing computations in your database: people who think it's great, and people who are wrong."

Aqui ilustro apenas que usar o JavaScript para 'fazer computações' no banco de dados oferece muitas vantagens em relação ao utilizar o PL/pgSQL.

Extendendo o servidor Web com ngx_http_js_module:

Assim como o plv8 permite consolidar a lógica de negócios no banco de dados, o módulo JS do Nginx permite criar roteamentos complexos, proxies, e lógicas de sub requisições diretamente no servidor web usando JavaScript.

//nginx.conf
http {
  js_import main from '/etc/nginx/js/main.js';
  server {
    listen 80;
    location / {
      js_content main.handler;
    }
  }
}

// main.js
export function handler(r) {
  if(r.uri.startsWith('/api')) {
    r.proxy_pass('http://api_backend');
  } else {
    r.proxy_pass('http://web_backend');
  }
}

Novamente um exemplo extremamente tosco, apenas como ilustração. Note que com esta abordagem, pode-se, por exemplo, criar api gateways altamente sofisticados e extremamente robustos. Algo que seria muito mais díficil e menos eficiente usando Lua por exemplo.

Conclusão:

O JavaScript evoluiu muito desde sua concepção, transformando-se de um mero instrumento para adicionar interatividade à páginas web em uma linguagem capaz de construir sistemas robustos e complexos. Entretanto, há uma necessidade imperativa de não perdermos de vista sua essência e propósito como uma linguagem de script, especialmente em ambientes de backend aonde existem diversas alternativas que são objetivamente melhores para desenvolver aplicações - quase sempre.

A integração de JavaScript com ferramentas como Nginx e Postgres, através de módulos como plv8 e ngx_http_js_module, abre portas para um novo mundo de possibilidades aonde o JavaScript é de fato a melhor ferrementa para realizar muitas tarefas no backend.

Um breve relato

Após todas essas considerações, gostaria de compartilhar um pouco da minha experiência pessoal como desenvolvedor web full stack aposentado. Conduzi uma empresa de desenvolvimento de software durante sete anos, tive a oportunidade de entregar uma variedade de produtos utilizando diferentes tecnologias e stacks, mas há um projeto que ocupa um lugar especial no meu coração e no qual me orgulho profundamente, o último deles, antes de seguir outro rumo na minha jornada profissional.

Como um grande fã de programação de bando de dados, eu já namorava com o plv8 há um tempo, tendo usado pontualmente em alguns produtos. Neste projeto fez total sentido implementar todas as regras de negócios única e exlusivamente dentro do banco de dados e foi all-in. Não existe um backend no sentido tradicional, toda logica referente a todos os CRUDs são tratadas apenas pelo plv8 dentro do postgres. A aplicação web adjacente é literamente converter uma requisão http em uma chamada de banco de dados, transformando diretamente os parametros da url ou body da requisição em uma query de sql sem qualque lógica.

Além disso, após considerar soluções como Kong e Krakend, optamos por construr um API Gateway seguindo os moldes apresentado, integrando com este e outros serviços não relacionados ao banco de dados, que, por curiosidade, foram desenvolvidos em Go e Java. Neste cénario especifico - não existe bala de prata - estas decições se provaram muito acertadas.

É com grande satisfação que relato que esta aplicação, além de ter sido entregue antes do prazo e abaixo custo - após ajustes pontuais durante a implantação do sistema na empresa contratante - está em operação por mais de três anos sem registrar uma única falha. Ao usar a ferramenta certa para cada tarefa, alcançamos um nível de maturidade técnica que me faz reiterar: sempre use a ferramenta certa.

Perguntas

  • O JavaScript está sendo usado muito além de seu propósito. Isso é algo positivo ou negativo?

  • Você que têm experiência com linguagens fortemente tipadas por natureza e voltadas para o desenvolvimento de aplicações (como Java/C#/Swift) qual é a sua opinião sobre o uso de JavaScript para constuir aplicações no servidor ou nativas?

  • O que você pensa sobre o uso de JavaScript para estender e controlar ferramentas como Nginx e Postgres? Isso representa uma quebra de paradigma para você ou é algo natural? Você já conhece ou utilizou o plv8 ou nginx js_module?

  • No desenvolvimento frontend, vemos também o JavaScript sendo levado para muito além de seus limites como linguagem de script, sendo utilizado para criar aplicações muito complexas. Na evolução contínua e natural da linguagem, deveríamos reconsiderar a especificação como uma linguagem de script e começar a moldá-lo mais explicitamente para a construção de aplicações web ou devemos 'deixar' novas soluções emergirem? Segundo o criador do JSON, deveriamos aposentar o JavaScript.

E ai programador, quero saber sua opinião, o que você pensa sobre tudo isso?

Carregando publicação patrocinada...
4

JavaScript necessita de uma "gambiarra".

Se formos levar ao pé da letra a maquina java é uma gambiarra em C/C++
Igual JS com V8/libuv(embora aqui tenhamos um event loop bem explicito)

adoção intrisíca da melhores práticas da orientação a objetos, dão ao Java uma abordagem estruturada para o desenvolvimento de aplicativos, permitindo a construção de sistemas complexos e de grande escala com requisitos rigorosos de confiabilidade e desempenho

Java não é a melhor linguagem OOP. Java nem adota muita coisa de OOP.
Java é o que é pelo marketing da Sun(que convenhamos era muito bom).
E deu muito certo. Parabéns pra Sun. E java não é ruim. Java é mais uma linguagem
que faz seu trabalho, tendo bons devs faz muito bem seu trabalho, assim com C#(que chamo de java da microsoft, já que eles basicamente copiaram e melhoraram os problemas de java)

basta ler a especificação.

Bota o link, ajuda muito em!

Quase sempre é interpretado pois são usados justamente.

Java é interpretado. Mas graças ao JIT(ele é interpretado e compilado ao mesmo tempo igual ao JS na V8 e nas outras engines)

JavaScript foi propositalmente escolhido para surfar em sua popularidade.

Foi uma parceria, o nome javascript pertencia a Sun e passou a ser da Oracle quando a mesma comprou a Sun. JS seria os irmão menor de java. Isso ta literalmente no site do Brendan.

funcionalidade de linguagens feitas para desenvolver aplicativos complexos

Isso é uma bobagem. Uma linguagem pode esconder as partes feias e o programador achar que ela foi feita para coisas complicadas. Mas as partes feias estão abstraídas!

Lua por exemplo, da pra vc fazer algo funcional ou oop. Mas vc vai ter que criar isso na mão(as partes feias) e vai poder usar de boa como uma linguagem quase igual as outras. Lua tem poucas palavras reservadas e esconde pouco as coisas.

Uma linguagem muito abstraida vai ajudar bastante para criar coisas. Pq parece que
ela foi feita pra criar coisas. Mas na verdade esta escondendo.
Isso é ruim? Nem um pouco. Mas não mesmo!

Patterns do GOF estão ai pra mostrar que problemas eles existem para sanar problemas de linguagens OOP. Que em linguagens funcionais poucos patterns fazem sentido, pq elas já tem todos os outros integrados.

Node/Typescript/Prisma parecem adotar padrões de design, abordagens de arquitetura e rationales que são típicos do Java, ou qualquer outra linguagem focada no desenvolvimento de aplicações como C#.

A resposta é mais simples do que parece. Os devs dessas linguagens saem delas. Mas eles não esquecem. Não querem aprender uma nova forma de criar coisas. Querem continuar como antes! Isso fica claro. Um dev que vem dessas outras linguagens carrega os maneirismo delas. O que acaba refletindo no código dela. Eu acho isso bem ruim. Mas não é o fim do mundo. (colocas Class palavra em js prova um pouco disso)

Js é uma linguagem OOP prototipica(linguagens prototipicas foram desenvolvidas para sanar problemas de linguagens OOP classicas).

Coloca class em JS(mesmo que quase fake) trás mais problemas que soluções. Pessoas vão usar achando que vai ter certos efeitos, mas nem todos os efeitos vão aparecer, criando problemas. Pois Js é prototipica, outra forma de obter oop. O pensamento precisa mudar!
O que é bem dificil kkkk Seria esse o motivo deste tipo de linguagem não fazer muito sucesso o pensamento tem que mudar e mudar é complicado!

JavaScript no desenvolvimento de back-end da Web não está em replicar a funcionalidade de linguagens feitas para desenvolver aplicativos complexos,

Concordo plenamente. O dev de outra linguagem deve aprender a linguagem que esta usando. Vale pra python, Go e outras.

Aqui ilustro apenas que usar o JavaScript para 'fazer computações' no banco de dados oferece muitas vantagens em relação ao utilizar o PL/pgSQL.

Nunca tinha ouvido falar no plv8 muito interessante!

módulo JS do Nginx

Pq não usar Lua que já vem integrado ao Nginx e é outra linguagem de script que é usada em tudo para fazer tudo como js?

todas as regras de negócios única e exlusivamente dentro do banco de dados e foi all-in.

Isso era bem comum. Antigamente o banco tinha de tudo. O que foi mudando com a evolução das coisas. Mudandos as regras pra aplicação e deixando menos coisas pro banco resolver!

Ao usar a ferramenta certa para cada tarefa

Concordo!

linguagens fortemente tipadas por natureza

Não existem artigos cientificos que provem que linguagens tipadas são melhores.
Ou resultam em menos problemas. Tudo que vejo são evidencias anedóticas!
Se a linguagem nasceu assim que continue, se não que não.
Se existem as tipadas e a não tipadas algum motivo tem! rsrsrsr

controlar ferramentas como Nginx e Postgres?

Penso que o Nginx ja tem Lua pra isso. Mas JS nele pode ajudar muito quem não quer aprender lua.

Já no caso do postgres pra mim é uma novidade. Nem sei o que pensar ainda!

deveríamos reconsiderar a especificação como uma linguagem de script

Acho que isso pouco importa no final! Java por exemplo começou como linguagem simples para embarcados. Depois foi mudando e chegamos onde chegamos. Mérito da sun.
Pegou o hype OO da época, e ajudou a moldar o pensamento OO de uma grande geração.
Embora esse pensamento não esteja lá muito certo. Muita gente acha que Java é o suprasumo do OO. Que ela implementa tudo correto e certo de OO. O que não é verdade!

Segundo o criador do JSON, deveriamos aposentar o JavaScript.

Ele fala isso pq esta promovendo uma nova linguagem.
E o que mais impactante que dizer que é pra aposentar o JS?
Logo quem, ele mesmo o cara mais famoso de Js que podemos dizer!

O impacto foi grande, bem grande e deu muito certo. Os holofotes foram para ele.
E ele pode mostrar uma "alternativa" que ele estava promovendo.

Errado? Não! Genial? tbm não, mas foi perspicas kkkk

Abraços bom texto.

1

Excelente. Muito obrigado por seus comentários muito pertinentes. De fato concordo com muita coisa que disse e dão pano para muito manga e boas discussões.

Primeiro, queria apenar responder alguns pontos.

Se formos levar ao pé da letra a maquina java é uma gambiarra em C/C++

Não, existe uma diferença fundamental. A JVM é parte integral e fundamental da especificação do Java, enquanto no JS:

"ECMAScript is not intended to be computationally self-sufficient; indeed, there are no provisions in it's specification for input of external data or output of computed results"

Pq não usar Lua que já vem integrado ao Nginx e é outra linguagem de script que é usada em tudo para fazer tudo como js?

Graças aos esforços colossais mencionados no ínicio do texto, O js é objetivamente melhor que o Lua em vários sentidos: ele é 'normalmente' mais rápido, oferece mais funcionalidades, e talvez o mais imporante, no cénario Web, que involve muita manipulação de JSON, faz mais sentido usar a ferramenta que trabalha nativamente com estes objetos. E isso também se aplica em porque usar o plv8 em muitos casos.

Não existem artigos cientificos que provem que linguagens tipadas são melhores.

Não existem artigos que provem que são melhores, por que de fato não são, mas que eles produzem código mais legivel e com menos erros, existem muitos.

Ou resultam em menos problemas. Tudo que vejo são evidencias anedóticas!

Não são apenas evidencias anedóticas, mas um simples fato, que as aplicações mais complexas que existem são tipadas: considere os sistemas operacionais, sistemas de gerenciamento de banco de dados, navegadores, compiladores, as aplicações por trás dos sistemas bancários, corporativos e de telecomunicações. Tudo é tipado. Tipos são ferramentas fundamentais para mapear problemas do mundo real em abstrações de software.

4

Não, existe uma diferença fundamental. A JVM é parte integral da especificação do Java,

É uma verdade mas não muda o que eu disse, de java vira arvore que vira bytecode que vira codigo de maquina e tudo isso com JIT(o que é igual ao V8).

Node por outro lado tem event loop se não me engano tem coisas em java com isso.
Com a implementação do pattern reactor.

Uma curiosidade: O proprio Nginx usa um event loop(pattern reactor.)
mas ele é escrito em C/C++

oferece diversas funcionalidades que o Lua não tem

É aquilo que eu disse antes. As funcionalidades com a parte feia escondida rsrsrss

muita manipulação de JSON, faz mais sentido usar JS que trabalha nativamente com estes objetos.

Entendi o ponto!

mas que eles produzem código mais legivel e com menos erros existem muitos.

Isso tem artigos?

1

É uma verdade mas não muda o que eu disse

Sei la eu acho que muda tudo, o Java foi feito para interagir com o mundo externo, o JavaScript, não. Esse é o ponto, não a maneira como é feito. Por isso o Node é uma gambiarra e a JVM não.

Isso tem artigos?

Sim.

https://web.cs.ucdavis.edu/~filkov/papers/lang_github.pdf

https://www.microsoft.com/en-us/research/wp-content/uploads/2017/09/gao2017javascript.pdf

Veja também que dei um editada na outra resposta.

Abraços