Neste artigo ensinarei como criar uma API Restful que executa comandos CRUD (Create, Read, Update, Delete) utilizando nodeJs e MongoDB.

Requisitos

NodeJS: Será necessário instalar a última versão estável (LTS) do NodeJS.

Editor de código: No tutorial estou utilizando Visual Studio Code, mas você pode utilizar o editor de sua escola: Visual Studio Code, Brackets, Notepad++, Sublime ou qualquer outro.

Terminal de comandos: Como estou utilizando o Visual Studio Code, que já tem um terminal de comandos embutido, utilizarei o terminal interno do VS Code (que roda o Windows Power Shell por baixo dos panos).

Criando o projeto

Abra o seu terminal na pasta que deseja criar o projeto e informe o comando:

npm init -y

O comando npm init cria um novo projeto Javascript, utilizamos a diretiva -y para que o npm utilize os parêmetros padrões para criar o projeto, sem ficar perguntando as peferências do usuário.

Após a execução do comando, um arquivo chamado package.json será criado:

O próximo passo será adicionar os pacotes necessários para iniciarmos como desenvolvimento da API. Vamos utilizar três pacotes: Nodemon, Express e Mongoose.

Nodemon é uma ferramenta que auxilia o desenvolvimento em node.js, reiniciando automaticamente o servidor node sempre que uma mudança é efetuada no código.

Para instalar o Nodemon basta informar o comando abaixo:

npm install -D nodemon

O próximo pacote que deverá ser instalado é o Express.

O express é um framework para NodeJS que tem como objetivo facilitar a utilização de métodos HTTP e de criar rotas.

Para instalar o Express basta informar o comando abaixo:

npm install express

O último pacote que instalaremos é o Mongoose.

Mongoose é uma lib que é utilizada para facilitar a comunicação e utilização do MongoDB em aplicações NodeJS.

Para instalar o Mongoose basta digitar o comando:

npm install mongoose

Agora, se você abrir o arquivo package.json você verá que foram adicionadas duas novas seções no arquivo:
devDependencies, que contém os pacotes que não acompanharão a aplicação final quando for gerado o pacote em produção.

Dependencies: que contém os pacotes que irão para produção, nesse caso o express e o mongoose.

Observação importante: O pacote nodemon também pode ser instalado com a diretiva -g (ao invés da -D), e com isso ela ficaria disponível em seu ambiente independente da aplicação que fosse criada.

Organização do projeto

Agora vamos organizar nossa aplicação em pastas, seguindo a estrutura abaixo:

Teremos uma pasta chamada src, que conterá todo nosso código fonte.

Dentro da pasta src, teremos mais duas pastas: src/models, que conterá as estruturas de dados (modelos lógicos da aplicação) e src/controllers, que conterá nossas funções.

Utilizarei os comandos abaixo para criar as pastas:

mkdir src/models
mkdir src/controllers

O resultado final deverá ser o seguinte

O último passo antes de iniciar com o desenvolvimento é alterar o arquivo package.json adicionando a linha abaixo dentro da sessão scripts:

Iniciando o Desenvolvimento

O próximo passo agora é iniciar o desenvolvimento da nossa aplicação.

Crie um arquivo chamado index.js dento da pasta src.

const express = require('express');
const app = express();
app.use(express.json());
app.listen(3000);

Esse trecho de código importa a dependência express e cria nosso servidor NodeJS na porta 3000.

Nesse momento seu servidor já pode ser iniciado através do comando npm run dev no terminal.

Criando o Banco de dados no MongoDB Atlas.

Com o intuito de simplificar o tutorial vamos utilizar o MongoDB Atlas.

MongoDB Atlas é um serviço de hospedagem de Bancos de Dados MongoDB gerenciado que utiliza os principais provedores de núvem do mercado como base (AWS, Google Cloud ou Azure).

O MongoDB Atlas oferece um tipo de cluster chamado M0 totalmente de graça, que pode ser utilizado para fins de aprendizado ou de teste. Para iniciar o uso do MongoDB Atlas, acesse o site https://www.mongodb.com/cloud/atlas . Caso ainda não tenha uma conta para esse serviço, crie uma conta através do link https://account.mongodb.com/account/register .

Após criar sua conta, efetue o login e então acesse a opção Clusters.
Selecione a opção Build a Cluster.

Selecione a opção Shared Clusters, que se enquadra na Free Tier.

Mantenha as opções padrão, conforme a imagem abaixo. Clique em Create Cluster.

Selecione a opção Database Access no menu lateral e em Add New Database User.

Informe o um nome e senha para seu novo usuário. Não se esqueça de anotar o usuário e senha pois utilizaremos essas informações posteriormente. Clique em Add User.

Retorne para a opção Clusters no Menu lateral, procure o Cluster que foi criado e clique em Connect.

Selecione a opção Connect your Application.

Clique no botão Copy e salve a ConnectionString em um documento de texto pois iremos utilizá-la posteriormente.

Agora podemos finalizar o arquivo index.js, alterando-o para o código abaixo:

const express = require('express');
const mongoose = require('mongoose');
const app = express();
const routes = require('./routes');

//Abaixo, cole a connectionString que foi obtida no portal da Mongodb Atlas. Substitua as opções <user> pelo nome do usuário e <password> pela senha criada
const connectionString = 'mongodb+srv://substitua aqui a sua connection string';

mongoose.connect(connectionString,{
    useNewUrlParser:true,
    useUnifiedTopology:true
});

app.use(express.json());

app.use(routes);

app.listen(3000);

O código acima importa um arquivo de rotas chamado routes (que ainda não foi criado) e inicia a conexão com o nosso banco de dados que foi criado no MongoDB Atlas.

Crie um arquivo chamado User.js dentro da pasta src/models

const mongoose = require('mongoose');

const UserSchema = new mongoose.Schema({
    name:String,
    address:String,
    phoneNumber:String,
    birthDate:Date
});

module.exports = mongoose.model('User',UserSchema);

Esse trecho de código importa o mongoose através do comando require, após isso é criado um objeto chamado UserSchema que tem por objetivo definir quais são as propriedades aceitas em nosso documento MongoDB.

Depois é chamado o comando module.exports passando o modelo criado, tornando-o disponível para outros arquivos consumí-lo.

Crie um arquivo chamado routes.js dentro da pasta src:

const {Router} = require('express');
const userController = require('./controllers/UserController');
const routes = Router();

routes.get('/users', userController.list);
routes.post('/users', userController.insert);
routes.put('/users/:id', userController.update);
routes.delete('/users/:id', userController.delete);

module.exports = routes;

O código acima importa o objeto Router de dentro do framework Express, um controller chamado userController (que ainda não foi criado).
Inicializa um objeto chamado routes e cria quatro rotas chamando quatro funções de dentro desse controller.

Agora só falta criarmos o Controller que irá conter as funções chamadas pelas nossas rotas. Crie um arquivo chamado userController dentro da pasta src/controllers contendo o código abaixo:

const User = require('../models/User');
const { response } = require('express');
module.exports = {  
    async list(req,res){
        const users = await User.find();
        return res.json(users);
    },
    async insert (req,res){
        const {name, address, phoneNumber, birthDate} = req.body;
     
        const user = await User.create({
            name, 
            address, 
            phoneNumber, 
            birthDate
        });
        
     res.json({success:true, user});
    },
    async update(req,res){
        const {id} = req.params;
        const {name, address, phoneNumber, birthDate} = req.body;
        let user = await User.findOne({_id:id});
        if(user){
            if(name) user.name = name;
            if(address) user.address = address;
            if(phoneNumber) user.phoneNumber = phoneNumber;
            if(birthDate) user.birthDate = birthDate;
    
            await User.update(user);
        }
        res.json({success:true, user});
    
    },
    async delete(req,res){
        const {id} = req.params;
        let user = await User.findOne({_id:id});
        if(user){
            await User.deleteOne({_id:id});
        }
        res.json({success:true});
    }
    }

Esse código importa o nosso modelo atribuindo-o para uma variável chamada User e também o objeto response de dentro do Express.

Então exportamos quatro funções assíncronas chamadas list, update, update e delete.

Pronto, você criou sua primeira web API utilizando NodeJs, Express e MongoDB!