Como Criar um Servidor em Node.js

Logo Node

O desafio neste post é criar um servidor em Node.js, organizando os arquivos de maneira que facilite a manutenção do projeto à medida em que ele cresce.

Me acompanhe que eu vou desde o básico, evoluindo gradativamente até chegarmos no objetivo.

Primeiro, vamos criar o servidor em um arquivo único. Obviamente, antes de iniciar, você precisa ter o Node instalado em sua máquina.

O Node é uma engine que permite a execução de código JavaScript fora do navegador. Isso deu a possibilidade de passarmos a utilizar JavaScript, que já dominava o client-side, também no server-side.

A fim de testar se o Node está ou foi devidamente instalado em sua máquina, abra uma janela do terminal e digite node -v. Isso deve retornar sua versão, indicando que ele está acessível e pronto para ser utilizado.

Checar a versão do node.

Crie uma pasta no local que você preferir, onde será configurado o servidor. A minha vai se chamar servidor-node.

Navegue para dentro da pasta. Se você tiver dúvidas a respeito de como trabalhar com o terminal, os dois artigos a seguir podem te ajudar, tanto no caso do Linux/Mac quanto do Windows.

Navegar para dentro da pasta onde será criado o servidor.

O Node também possui o npm (Node Package Manager) um gerenciador de pacotes. Ele geralmente é instalado juntamente com o Node, mas para desencargo, você também pode executar um npm -v no terminal e verificar.

Agora então vamos, de fato, iniciar um projeto Node. O comando para isso é o npm init.

Este utilitário irá me guiar pelos primeiros passos, permitindo informar coisas como o nome do projeto, versão, descrição, etc.

Alguns campos já vêm com uma sugestão, como é o caso do nome e da versão. Caso você não queira o valor que já veio preenchido, basta informar o novo valor, da forma como fizemos para o campo versão, ilustrado na imagem abaixo.

Iniciar um projeto node.

Um campo que merece nossa atenção neste ponto é o entry point, pois é o arquivo informado nele que será executado para iniciar nossa aplicação.

Geralmente esse arquivo é chamado de index.js, motivo que justifica a sugestão para o campo.

Quando você termina de preencher os campos e pressiona Enter, é gerado dentro da pasta do seu projeto um arquivo de extensão json, com os dados informados.

Esse é um arquivo que descreve o projeto, e você irá entendê-lo melhor no decorrer do post.

Arquivo de descrição do projeto node criado.

Como o entry point será o index.js, precisamos criar este arquivo na raiz do nosso projeto. Utilize a IDE que você preferir, eu vou usar o Sublime Text.

Criar entry point em um projeto node.

Quando desenvolvemos uma aplicação, frequentemente utilizamos bibliotecas externas. Em Node, elas são chamadas de libs.

Para criar o nosso servidor, vamos utilizar uma lib aqui chamada Express. Ela implementa toda a parte das requisições e respostas com o protocolo http. Para que o cliente, geralmente um navegador, possa trocar informações de forma segura com o servidor.

Implementar manualmente tudo o que essa biblioteca fará por nós, demandaria uma expertise muito grande, daria um trabalho danado e, provavelmente, o resultado não seria tão minimalista, otimizado e seguro como o Express comsegue ser.

Instalaremos a lib do Express com o gerenciador de pacotes npm, começando com o comando npm install. Também vamos pedir para que essa informação seja salva acrescentando o parâmetro --save e, em seguida, o nome da lib: express. O comando completo encontra-se abaixo:

npm install --save express

Aí você pode estar se perguntando: mas onde isso é salvo? Bom, o package.json descreve o projeto. Se você der uma olhada novamente no arquivo, vai perceber que foi adicionado a ele uma nova chave, a chave das dependências, ou seja, de que este projeto depende para funcionar.

Você também deve ter reparado no surgimento de uma nova pasta no projeto, chamada node_modules. É alí que ficam os arquivos das dependências listadas no package.json.

Chave das dependências de um projeto node.

Antes de você compartilhar o projeto com outra pessoa ou executá-lo em outra máquina, é uma boa prática remover a pasta node_modules. Dessa forma, quando a outra pessoa receber o projeto, ela deve executar o comando npm install, que irá ler o arquivo package.json e baixar novamente as dependências, de acordo com a arquitetura de sua máquina e sistema operacional.

O próximo passo é importar esse módulo espress que acabamos de baixar, para dentro do nosso arquivo index.js.

Em Node, quando queremos importar um módulo, utilizamos a expressão require.

O que vamos fazer neste ponto, é criar uma constante chamada express que irá receber a importação do módulo.

const express = require('express');
Importar módulo em projeto node.

Com a linha de código acima, apenas carregamos o módulo Express na constante. Precisamos ainda criar uma instância desse objeto e guardá-la em uma nova constante, que vamos denominar app.

const app = express();
Invocar módulo Node importado.

Ok, agora toda vez que nos referirmos à app, estaremos falando do Express.

Para colocar um servidor de pé com o Express, a primeira coisa que devemos fazer é dizer que ele estará pronto para ouvir requisições em uma determinada porta. Então vamos pegar a app, executar o método listen informando a porta. Por convenção, os servidores Node escutam na porta 3000, mas nada impede de você escolher qualquer outra.

app.listen(3000);

Só isso já é suficiente para que tenhamos uma thread rodando. Mas do jeito que está, não terá como ver se está ou não funcionando. Para que tenhamos algum feedback, vamos passar como segundo parâmetro do método listen, uma função callback (declarada observando a sintaxe das Arrow Functions) que vai me mostrar um log com a seguinte mensagem: "Servidor ouvindo na porta 3000".

Colocando um Servidor Node de pé com o método listen do Express.

E por fim, estando com o terminal dentro da pasta onde encontra-se nosso arquivo index.js, podemos executá-lo utilizando o Node. Isso é feito escrevendo-se node, espaço, nome do arquivo.

node index.js
Executando um script com node pelo terminal.

O log comprova que o servidor está rodando. Mas se abrirmos o navegador e fizermos uma requisição para o endereço localhost na porta 3000, ainda não veremos nada porque o navegador tentará fazer uma requisição http do tipo get para a rota barra /, e ainda não definimos o que o servidor deve fazer ao receber um get para esta rota.

Acessando localhost na porta 3000.

Criaremos essa rota utilizando o método get do Express. O método receberá, como primeiro parâmetro, uma string determinando a rota e, como segundo parâmetro, novamente uma função callback, onde será declarado o que faremos quando essa rota for acessada.

Nessa função callback, nós vamos receber como parâmetro dois objetos: um referente ao request, que eu vou abreviar para req e outro referente ao response, que vou chamar de res.

No corpo da função, vou pegar o objeto res e chamar o método send, para enviar uma resposta ao navegador dizendo que a rota barra foi acessada.

Criando rota barra no Express.

Executando novamente o servidor e acessando o endereço localhost:3000 no navegador, obtemos a resposta programada.

Rota barra atendida.

Arquiteturando melhor o projeto

Em um projeto grande, provavelmente o Express vai receber várias customizações e muitas rotas serão criadas.

Além do mais, o arquivo index.js está com muitas responsabilidades. Ele importa o Express, cria uma instância do mesmo, inicia o servidor e atende requisições. Quando deveria somente ser responsável por iniciar o servidor.

A primeira coisa que iremos fazer então, é criar uma pasta chamada src (source) na raiz do projeto, onde estarão todos os arquivos da nossa aplicação.

Dentro de src, teremos uma pasta denominada config – para isolar as configuraões. E outra, chamada app – que irá conter o cerne de nossa aplicação.

Dentro de config, criaremos o arquivo custom-express.js. Local em que irão se concentrar todas as customizações referentes a esta lib. Dessa forma, já podemos mover as configurações do Express, que estão no arquivo index.js, para o novo destino.

Pasta config contendo o arquivo custom-express.

O arquivo foi chamado de custom-express porque ali irão se concentrar todas as customizações referentes ao Express, que provavelmente serão necessárias à medida que o projeto for crescendo.

E agora, no arquivos index.js, em vez de importar o Express padrão através do require, importaremos o Express customizado.

Importando Express customizado no arquivo index.js.

Referente à string de importação do módulo na imagem acima, o que fiz foi partir da pasta atual ., entrar na pasta src /src, seguir para config /config e acessar o módulo criado por nós, /custom-express.

Se o require importa, a sintaxe que exporta um módulo é a module.exports. Portanto, para que nosso servidor continue funcionando, precisamos fazer essa declaração lá no módulo do Express customizado.

Exportar um módulo em Node.

Agora é hora de colocar nossas rotas também em um arquivo separado. Pensando no modelo MVC, elas seriam nossos controladores. Por isso, criarei uma pasta controllers no projeto para comportar nossas rotas. Dentro dessa pasta, vou criar o arquivo raiz.js que irá conter a única rota que temos até o momento.

Colocando as rotas de um projeto Node em um arquivo separado.

Farei a importação das rotas lá no Express, que é justamente o cara responsável por cuidar delas.

O meu módulo controllers vai estar configurado para que, ao ser chamado, retorne uma função com as rotas. Por isso, aqui em custom-express.js, logo após a importação, irei chamar essa função passando a app, justamente para obter as rotas. É como se eu encaixasse todas as rotas naquele ponto onde a função foi chamada.

Importando as rotas para dentro do Express.

Na string de importação do módulo rotas, meu ponto inicial é o arquivo custom-express.js e desejo acessar o arquivo raiz.js. Para isso, primeiramente naveguei para fora da pasta atual .., depois, informei o caminho até o arquivo raiz.js.

E por último, para que tudo continue funcionando, vamos então exportar a tal função com as rotas.

Exportando função de um módulo node.

Repare que recortamos a rota já previamente criada no arquivo index.js e a trouxemos para o arquivo raiz.js. Lembrando ainda, que a sintaxe da função está de acordo com a das Arrow Functions.

Abstraindo um pouco os caminhos de pasta

Organizado do jeito que está, já é melhor do que em um arquivo único. Porém, todo novo conjunto de rotas que formos criando, teremos que importar manualmente no Express. Essa solução é um pouco engessada, ou como o pessoal gosta de falar para ficar mais chique: hard-coded, ou seja, se mudarmos a estrutura de pastas do projeto, ele quebra.

Isso é ruim, porque a mudança, inevitavelmente, vai ocorrer. Essa é a única certeza que temos.

Nesse sentido, iremos lançar mão de um módulo chamado consign que irá nos auxiliar na organização das pasta do projeto.

Faremos a instalação dessa lib, com o já conhecido gerenciador de pacotes do node, o npm.

npm install --save consign

Depois de instalado, importamos o Consign no arquivo onde estamos customizando o Express. Invocamos o mesmo através da sintaxe consign(), e aí, basta mandar incluir a pasta controllers .include('src/app/controllers') dentro da app, .into(app);.

consign().include('src/app/controllers').into(app);
Importar rotas através do Consign em um projeto Node.

Com isso, toda nova rota já será importada automaticamente. Tanto isso é verdade que, se rodarmos novamente nosso servidor, já veremos logs do Consign com os arquivos detectados dentro da pasta rotas.

Consign detectando rotas automaticamente.

Caso ainda tenha restado alguma dúvida, aqui estão os arquivos do projeto, resultantes do passo a passo mostrado no decorrer do artigo.

Artigos Relacionados

Ir para o topo