Express, Koa, Meteor, Sails.js: quatro estruturas do apocalipse

Publicados: 2022-03-11

O JavaScript definitivamente se tornou uma das linguagens mais populares nos últimos anos, devido à enorme demanda por aplicativos da web. Ao codificar para vários navegadores, o JavaScript é quase a única opção para desenvolvedores front-end. Pode-se argumentar que há CoffeeScript, TypeScript ou Dart como alternativas. No entanto, a verdade é que o CoffeeScript é visto principalmente como um açúcar sintático que eventualmente se resume ao JavaScript. TypeScript é simplesmente um superconjunto de JavaScript que inclui vários recursos de linguagem orientada a objetos, como tipagem estática opcional, classes e interfaces, e ainda está em seus primeiros dias. Dart também é uma linguagem orientada a objetos que possui sintaxe semelhante a C, mas ainda compila em JavaScript para navegadores convencionais.

Com o nascimento e o rápido crescimento do Node.js, o JavaScript não está mais confinado ao desenvolvimento de front-end, e o desenvolvimento de back-end não é mais ciência do foguete para codificadores de front-end. As pessoas tendem a pensar no JavaScript como uma bala de prata que se encaixa em todas as situações: front-end, servidor web, aplicativo de desktop, sistema embarcado, bancos de dados… a lista só aumenta. Na verdade, dado o amplo público de JavaScript, Node.js+MongoDB+AngularJS/React fez uma grande quantidade de desenvolvedores web full stack. No entanto, o Node.js foi projetado para ser leve e fornece apenas funcionalidades fundamentais como servidor web para aumentar a velocidade de desenvolvimento de aplicativos web. Uma das estruturas prontas para uso disponíveis como pacotes npm seria uma opção melhor no mundo real.

Neste post, veremos alguns desses frameworks Node.js bem conhecidos e testados ao longo do tempo que aliviaram os desenvolvedores de ter que reinventar a roda repetidamente. Para ser mais específico, neste artigo veremos Express, Koa, Meteor e Sails.js. Em vez de tentar descobrir como cada uma dessas estruturas se comparam umas às outras, veremos as principais áreas nas quais cada uma dessas estruturas se destaca e como elas são relevantes para as várias necessidades do projeto.

Express: um framework web minimalista

Escusado será dizer que o Express é o maior negócio para os negócios do Node.js. Todo jogador do Node.js já ouviu falar dele e está usando com ou sem perceber. Ele está atualmente em sua 4ª geração, e existem alguns frameworks Node.js construídos com base nele ou inspirados por seus conceitos.

atuação

A maioria dos desenvolvedores adora o Node.js por sua velocidade bruta e, quando se trata de seleção de framework, um perfeccionista pode desdenhar qualquer risco de desempenho. O Express fornece uma camada fina sobre o Node.js com recursos de aplicativos da Web, como roteamento básico, middleware, mecanismo de modelo e serviço de arquivos estáticos, para que o desempenho de E/S drástico do Node.js não seja comprometido.

Express é uma estrutura mínima e sem opinião. ele não aplica nenhum dos padrões de design predominantes, como MVC, MVP, MVVM ou qualquer outra tendência pronta para uso. Para os fãs de simplicidade, essa é uma grande vantagem entre todos os outros frameworks, porque você pode construir seu aplicativo com sua própria preferência e sem curvas de aprendizado desnecessárias. Isso é especialmente vantajoso ao criar um novo projeto pessoal sem carga histórica, mas à medida que o projeto ou a equipe de desenvolvimento cresce, a falta de padronização pode levar a um trabalho extra para gerenciamento de projeto/código e, no pior cenário, pode levar à incapacidade de manter .

Gerador

Mesmo que o framework não seja opinativo, ele possui o gerador que gera a estrutura de pastas do projeto específico. Depois de instalar o pacote npm express-generator e criar o esqueleto do aplicativo com o comando generator, uma pasta do aplicativo com hierarquia clara será criada para ajudá-lo a organizar imagens, JavaScript estático de front-end, arquivos de folha de estilo e arquivos de modelo HTML.

 npm install express-generator -g express helloapp
 create : helloapp create : helloapp/package.json create : helloapp/app.js create : helloapp/public create : helloapp/public/images create : helloapp/routes create : helloapp/routes/index.js create : helloapp/routes/users.js create : helloapp/public/stylesheets create : helloapp/public/stylesheets/style.css create : helloapp/views create : helloapp/views/index.jade create : helloapp/views/layout.jade create : helloapp/views/error.jade create : helloapp/bin create : helloapp/bin/www install dependencies: $ cd helloapp && npm install run the app: $ DEBUG=helloapp:* npm start create : helloapp/public/javascripts

Middleware

Middleware são basicamente apenas funções que têm acesso total aos objetos de solicitação e resposta.

Pilha de tratamento de solicitações

Como o nome indica, o middleware aplica algumas instruções de filtragem antes de passar o controle para a lógica de negócios real ou para o próximo nível de middleware. Algumas tarefas comuns, como verificar o status de login do usuário, validar a autoridade do usuário ou impedir ataques entre sites, são melhor extraídas como middleware.

 var app = express(); app.use(cookieParser()); app.use(bodyParser()); app.use(logger()); app.use(authentication()); app.get('/', function (req, res) { // ... }); app.listen(3000);

Um aplicativo Express é essencialmente Node.js com uma série de funções de middleware, se você deseja personalizar seu próprio middleware ou aproveitar os middlewares integrados da estrutura, o Express tornou o processo natural e intuitivo.

Mecanismo de modelo

Os mecanismos de modelo permitem que o desenvolvedor incorpore variáveis ​​de backend em arquivos HTML e, quando solicitado, o arquivo de modelo será renderizado no formato HTML simples com as variáveis ​​interpoladas com seus valores reais. Por padrão, o express-generator usa o mecanismo de modelo Pug (originalmente conhecido como Jade), mas outras opções, como Mustache e EJS, também funcionam perfeitamente com o Express.

Integração de banco de dados

Como uma estrutura mínima, o Express não considera a integração de banco de dados como um aspecto obrigatório em seu pacote, portanto, não se inclina para nenhum uso específico de banco de dados. Ao adotar uma determinada tecnologia de armazenamento de dados, seja MySQL, MongoDB, PostgreSQL, Redis, ElasticSearch ou qualquer outra, basta instalar o pacote npm específico como driver de banco de dados. Esses drivers de banco de dados de terceiros não estão em conformidade com a sintaxe unificada ao executar instruções CRUD, o que torna a troca de bancos de dados um grande problema e propenso a erros.

Koa: utilizando recursos JavaScript de próxima geração

O Koa é desenvolvido pela equipe por trás do Express, e seu objetivo é minimizar o Express minimalista, não agrupando nenhum middleware em seu núcleo. Além de não ter middleware, o Koa é muito parecido com o Express, leve e sem opinião. No entanto, o que torna o Koa realmente destacado é sua maneira de abandonar completamente o retorno de chamada usando o recurso ES6 Generator.

Fluxo de controle elegante

Javascript é uma linguagem de programação assíncrona e, com esse instinto da própria linguagem e o mecanismo orientado a eventos de thread único do Node.js, o retorno de chamada está em todo lugar, daí o notório inferno de retorno de chamada.

Uma maneira de nivelar o aninhamento de retorno de chamada é usar Async.js. Async.js fornece técnicas para mapear, paralelizar, serializar ou iterar várias funções sem ter que incorporar uma na outra e, em seguida, passar o fluxo de controle com uma função de retorno de chamada, um retorno de chamada e uma função de tratamento de erros são suficientes para a maioria das funções agrupadas por um método Async.js. No entanto, o Async.js não pode eliminar totalmente os retornos de chamada. Ao escrever código Node.js com Async.js, o recuo do código ainda tende a se deslocar para a direita, mas não tão profundo.

Fuja do inferno de retorno de chamada

Outra maneira mais limpa é usar Promises então habilitadas. Algumas bibliotecas Promise de terceiros com reputação são bluebird e q. Na mais nova edição do JavaScript, ES6, o Promise foi adotado como uma padronização. Para encurtar a história, o Promise garante que as funções sejam executadas e retornadas de maneira sequencial, conectando os blocos/funções de implementação com um monte de funções do Promise “then”. Ou você “resolve” no final de cada bloco/função de implementação para que a próxima função “depois” seja executada, ou você “rejeita” a implementação a seguir para que o fluxo de controle vá direto para o tratamento de erros. Dessa forma, você agrega todas as funções de tratamento de erros em um só lugar e se livra completamente dos retornos de chamada.

Agora o ES6 traz um divisor de águas para a mesa — o ES6 Generator. Essa noção é nova para JavaScript, mas não é nova no mundo da programação. O ES6 Generator é como a interrupção em C, em vez de executar linhas de código de cima para baixo, o ES6 Generator introduz um meio de executar->parar e executar outra coisa->voltar para terminar o que sobrou.

Koa está utilizando geradores ES6 para fornecer uma maneira elegante de lidar com programação assíncrona JavaScript, portanto, você não pode ver retornos de chamada em um aplicativo Koa puro. Um caso de uso típico do ES6 Generator no Koa é o middleware em cascata, que permite que o middleware personalizado seja executado um após o outro sem nenhum retorno de chamada desagradável.

 var app = koa(); function* responseTimeLogger(next){ var start = new Date; yield next; var ms = new Date - start; console.log(this.method + ' ' + this.url + ': ' + ms); } app.use(responseTimeLogger); // ... app.listen(3000);

Não podemos tirar conclusões precipitadas afirmando que esta técnica de ponta é superior às soluções da velha escola, como Async.js, Promise ou emissor de eventos, mas uma coisa é certa: esse novo conceito leva algum tempo para se acostumar. Com a sequência de fluxo de controle não convencional, pode trazer dificuldade extra para depuração de código.

Meteor: Framework para Web, Mobile e Desktop

Meteor é um framework JavaScript completo. Diferenciando-se da filosofia de simplificação do Express e Koa, ele vai ao outro extremo ao se definir como um framework full-stack, um pacote completo que abrange aplicativos de servidor, mobile, desktop e web.

Pacote um para todos

Se você olhar de perto, notará que o Meteor é realmente Node.js+Blaze/AngularJS/React+Cordova+MongoDB. Node.js e MongoDB são respectivamente responsáveis ​​pela lógica de negócios do lado do servidor e armazenamento de dados. Um dos Blaze, AngularJS ou React cuida da interface do usuário de front-end. E o Cordova, como a solução HTML mais famosa para aplicativos híbridos móveis, conecta páginas da Web a visualizações móveis.

Sincronização de dados

O processo principal de back-end e front-end para compartilhar dados é o seguinte:

  • O cliente solicita dados ou determinada visualização HTML
  • O servidor recupera dados do banco de dados, mistura os dados com a visualização HTML usando algum mecanismo de modelagem e os envia de volta ao front-end
  • O cliente renderiza e mostra os dados/visualização de forma amigável

Um aplicativo web moderno de página única ajusta um pouco o processo acima. Tome o AngularJS como exemplo, ele coloca templates HTML como arquivos estáticos junto com outros ativos, como arquivos JavaScript front-end, folhas de estilo e imagens. O AngularJS então preenche os dados nos modelos HTML solicitando dados ao back-end usando a API RESTful Ajax. De qualquer forma, os desenvolvedores de back-end são totalmente responsáveis ​​por lidar com as solicitações de alteração de dados do front-end e salvar as alterações no banco de dados.

sincronização de dados bidirecional realizada automaticamente

Uma das características que distingue o Meteor de outros frameworks é seu mecanismo de sincronização de dados entre servidor e aplicativos front-end/mobile. No Meteor, o cliente mantém uma cópia de sombra do mini-banco de dados que é uma pequena parte da replicação do banco de dados do servidor, uma parte que é previamente solicitada pelo cliente e autorizada pelo servidor. Quando o cliente deseja fazer qualquer alteração nos dados, ele usa a API de banco de dados consistente como lado do servidor para executar qualquer instrução CRUD e, em seguida, as alterações de dados serão enviadas automaticamente para o servidor e salvas no banco de dados real. Sempre que o servidor detecta qualquer modificação de dados, ele envia os dados atualizados para clientes específicos que assinam esses dados. Esta sincronização de dados bidirecional é realizada automaticamente sem qualquer intervenção manual. Para criar essa mágica, o Meteor está usando o WebSocket para conectar o cliente e o servidor sob o capô, para que qualquer alteração de dados em uma extremidade seja refletida na outra instantaneamente.

Ferramenta de automação de compilação

O Meteor não apenas cuida de aplicativos de servidor e web, usando a ferramenta de construção do Meteor chamada Isobuild com a ajuda do Cordova, uma biblioteca que agrupa HTML/JavaScript/CSS com funcionalidades móveis nativas, o Meteor facilita muito a construção de aplicativos iOS e Android. Os aplicativos móveis gerados são aplicativos híbridos que executam JavaScript ou mostram páginas HTML dentro de um WebView. Essa solução alternativa pode comprometer a experiência do usuário quando comparada aos aplicativos móveis nativos, mas, para muitos, poder gerenciar tudo na mesma base de código com aplicativos da Web é um grande ponto de venda e economiza muito custo de desenvolvimento.

No geral, o Meteor é um framework altamente automatizado. Essa automação de alto nível torna a vida dos desenvolvedores muito mais fácil, mas traz um custo de desempenho prejudicado e restrições de escalabilidade. À medida que a base de usuários cresce, a técnica de sincronização automatizada de dados torna-se o ponto de estrangulamento de escala. Para obter a mesma capacidade e desempenho de outras tecnologias de back-end ajustadas manualmente, o Meteor geralmente consome muito mais recursos de hardware e largura de banda de servidor. Portanto, o Meteor pode ser um ótimo ponto de partida e uma caixa de ferramentas perfeita se alguém quiser prototipar um projeto para todas as principais plataformas, mas eventualmente em algum momento a arquitetura do sistema precisa ser redesenhada de maneira mais profissional se o protótipo se tornar um projeto de produção com suficiente base de clientes.

Sails.js: estrutura MVC superior para Node.js

O Sails.js compartilha muitas semelhanças com o Express. É um gerador de projetos, middleware e mecanismo de modelagem. Na verdade, é construído em cima do Express, além de algumas funcionalidades de nível superior para acelerar o desenvolvimento.

MVC

Controlador de exibição de modelo

Sails.js adota o padrão de design Model-View-Controller de seu núcleo. Para aqueles que vêm de Ruby on Rails ou Laravel, eles acharão a estrutura de um aplicativo Sails.js muito familiar. O modelo representa o modelo de dados que reflete o esquema da tabela/coleção do banco de dados, a exibição é a exibição HTML com dados preenchidos, o controlador é onde você coloca toda a lógica de negócios do lado do servidor e atua como uma cola entre os dados e a exibição.

Comunicação em tempo real

Não como uma solicitação HTTP em que o cliente precisa consultar dados do servidor todas as vezes, ou uma longa conexão de pesquisa que coloca o servidor em modo inativo, o Socket.io estabelece uma comunicação bidirecional baseada em eventos entre cliente e servidor. O Sails.js integra o Socket.io e o envolve com alguma API de nível de abstração mais alto para fornecer mais conveniência, tornando o Sails.js especialmente adequado para criar aplicativos de bate-papo ou jogos multiplayer.

Banco de dados ORM

Banco de dados ORM

Entre a lógica de back-end e a manipulação real do banco de dados, existe uma camada ORM intermediária chamada Waterline. Simplificando, essa ferramenta ORM fornece uma sintaxe consistente para acessar diferentes bancos de dados sem que os desenvolvedores precisem se preocupar com linguagens de consulta de banco de dados variadas, como SQL vs NoSQL, esquema vs sem esquema e assim por diante.

Sails.js tem um grau de automação intermediário. Ele se concentra na lógica do lado do servidor e está pronto para produção, e fornece um ritmo de desenvolvimento mais rápido do que o Express, sem sacrificar qualquer desempenho ou escalabilidade futura. Em particular para a grande quantidade de devotos do padrão MVC, o Sails.js tem uma curva de aprendizado bastante suave.

Embrulhar

Este artigo não está classificando diferentes estruturas Node.js, mas lista os pontos brilhantes de cada estrutura para se destacar da multidão e ajudar os desenvolvedores Node.js a escolher a caixa de ferramentas mais adequada ao criar um projeto do zero.

Então, qual é o seu framework Node.js favorito para desenvolvimento web? Você prefere algum framework diferente dos que discutimos acima? Deixe-nos saber na seção de comentários abaixo.

Relacionado:
  • Por que diabos eu usaria o Node.js? Um tutorial caso a caso
  • Cabin Fever Coding: um tutorial de back-end do Node.js
  • Como criar uma API REST Node.js/TypeScript, Parte 1: Express.js