Criação de uma aplicação CRUD utilizando Node.js e MongoDB (Ubuntu 18.04) — Parte 2/2

Cristiano Patrício
8 min readApr 3, 2019

--

Na parte 1/2 criámos o projeto e vimos o funcionamento dos métodos GET e POST. Fizemos uso de ficheiros .ejs para tornar a aplicação mais user friendly e representar graficamente os elementos da nossa aplicação.

Passo 7) Ligação à Base de Dados MongoDB

Para usar o MongoDB precisamos de instalá-lo, para isso basta executar o seguinte comando:

user@ubuntu:~/Desktop/books_app$ npm install mongodb --save

Para fazer a ligação à base de dados, precisamos primeiro de a criar. Vamos criar uma conta no https://www.mongodb.com/cloud/atlas

Depois de iniciar sessão, vamos proceder à criação de um cluster com o nome ‘crud-nodejs’, por exemplo.

De seguida, vamos criar a base de dados e uma collection, para isso, basta ir a COLLECTIONS > Create New Database e preencher os campos:

Vamos agora proceder à criação de um utilizador da base de dados, com os privilégios de leitura e escrita na base de dados.

Na aba Security > Add New User

A string de ligação do MongoDB está disponível em Connect > Connect your application

Se clicarmos em ‘Full Driver Example’, temos acesso a todo o código que permite fazer a ligação da base de dados MongoDB para o driver Node.js. Vamos fazer Copy do código exemplo.

De seguida, vamos adicionar o código exemplo copiado ao nosso ficheiro index.js, fazendo as alterações necessárias, nomeadamente, substituir <password> pela password definida, bem como o nome da base de dados e o nome da collection que definimos anteriormente. (Base de Dados: mongodb Collection: books).

Queremos que o servidor só inicie quando a base de dados estabelecer a ligação. Para isso, vamos colocar o código do app.listen dentro do método connect.

const MongoClient = require('mongodb').MongoClient;
const uri = "mongodb+srv://robot:robot@crud-nodejs-aamhl.mongodb.net/test?retryWrites=true";
const client = new MongoClient(uri, { useNewUrlParser: true });
client.connect(err => {
db = client.db("mongodb").collection("books");
app.listen(3001, function(){
console.log("O servidor está a correr na porta 3001");
});
});

Depois das alterações deverá ter algo do género:

Pode testar se a ligação foi bem sucedida, vamos iniciar o servidor executando o comando node index.js. Caso o output na consola seja a string passada no console.log no método listen, então está tudo a funcionar!

Passo 8) Operações CRUD

Agora que configurámos o MongoDB, vamos criar uma coleção para armazenar os dados dos campos do formulário. Uma coleção armazena objetos, no caso do nosso projeto irá armazenar os dados do ‘title’, ‘author’ e ‘genre’, relativos a um dado livro.

  1. Guardar os dados na base de dados — CREATE

Uma vez que já criámos a coleção ‘books’, aquando da criação da base de dados, apenas temos de invocar o método insertOne() do MongoDB, que permite guardar um registo na base de dados.

Assim que guardamos o nosso registo, queremos que a página seja redirecionada para algum lugar, caso contrário ficamos a aguardar até que o servidor sofra alguma alteração. Assim, vamos redirecionar para ‘/’, após a inserção de um registo na base de dados.

Vamos alterar o método app.post no nosso ficheiro index.js.

app.post('/show', (req, res) => {
db.insertOne(req.body, (err, result) => {
if (err) return console.log("Erro: " + err);

console.log("Registo guardado com sucesso na BD!");
res.redirect('/');
});
});

Para ver se está a funcionar corretamente, reinicie o servidor e preencha o formulário. Após carregar no botão ‘Submit’, abra o terminal e deverá aparecer a mensagem de sucesso:

Pode ver a entrada de dados no dashboard do Atlas MongoDB, na Aba ‘Collections

2. Ler dados da base de dados — READ

Para mostrar os dados da base de dados numa página, temos de obter os dados da base de dados e utilizar a template engine para mostrar os dados:

Para obter os dados da base de dados, usamos o método find() . Vamos adicionar o seguinte código no ficheiro index.js.

app.get('/', (req, res) => {
const cursor = db.find();
});

O método find() retorna um cursor (um objeto do Mongo), este objeto contém os registos da nossa base de dados. Tem várias outras propriedades e métodos que nos permitem trabalhar com dados facilmente. Um desses métodos é o método toArray.

O método toArray recebe uma função callback que nos permite fazer algumas coisas com os objetos que recuperamos do Atlas MongoDB.

Vamos fazer um console.log() desses resultados.

Vamos acrescentar as seguintes linhas de código ao ficheiro index.js dentro do método post.

db.find().toArray((err, results) => {
console.log(results);
});

Vamos correr o servidor, preencher o formulário e carregar no botão ‘Submit’. Devemos obter o seguinte resultado no terminal:

Como podemos observar, temos dois registos porque já estava um na base de dados, que inserimos há pouco.

3. Renderizar o conteúdo num template engine

Vamos criar um ficheiro dentro do diretório ‘views’ com o nome “show.ejs”:

user@ubuntu:~/Desktop/books_app$ cd views
user@ubuntu:~/Desktop/books_app/views$ touch show.ejs

Agora vamos abrir o ficheiro show.ejs

user@ubuntu:~/Desktop/books_app/views$ gedit show.ejs

e incluir o seguinte código, que basicamente representa uma tabela onde vão ser mostrados os dados:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Books Repository</title>
</head>
<body>
<h2>Records<h2>
<table border="1">
<thead>
<tr>
<td>Title</td>
<td>Author</td>
<td>Genre</td>
</tr>
</thead>
<tbody>
<% data.forEach(function(details) { %>
<tr>
<td><%= details.title %></td>
<td><%= details.author %></td>
<td><%= details.genre %></td>
</tr>
<% }) %>
</tbody>
<button><a href="/">Back</a></button>
</body>
</html>

Na linha 19 estamos a utilizar a variável books com o método forEach, que irá percorrer todo o conteúdo da collection ‘books’ na base de dados.

De seguida, vamos acrescentar alguns métodos no nosso ficheiro index.js.

app.get('/show', (req, res) => {
db.find().toArray((err, results) => {
if (err) return console.log("Error: "+ err);
res.render('show.ejs', { books: results });
});
});

O resultado final deverá ficar como:

Vamos voltar a correr o nosso servidor e preencher o formulário. Quando clicarmos no botão ‘Submit’ iremos ser redirecionados para http://localhost:3001/show, e veremos então os registos existentes na Base de Dados.

4. Atualizar os dados— UPDATE

A operação Update é utilizada quando se pretende alterar determinado conteúdo da base de dados.

Vamos adicionar botões no template show.ejs’ para que possamos navegar para a página ‘Edit’ e ‘Delete’.

user@ubuntu:~/Desktop/books_app$ cd views
user@ubuntu:~/Desktop/books_app/views$ gedit show.ejs

Adicionar o seguinte código

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Books Repository</title>
</head>
<body>
<h2>Records<h2>
<table border="1">
<thead>
<tr>
<td>Title</td>
<td>Author</td>
<td>Genre</td>
</tr>
</thead>
<tbody>
<% books.forEach(function(details) { %>
<tr>
<td><%= details.title %></td>
<td><%= details.author %></td>
<td><%= details.genre %></td>
<td><a href="/edit/<%= details._id %>">Edit</a> | <a href="/delete/<%= details._id %>">Delete</a></td>
</tr>
<% }) %>
</tbody>
<button><a href="/">Insert New</a></button>
</body>
</html>

De forma a simplificar o código, iremos criar rotas (routes) para as operações CRUD.

Em cada uma das rotas, podemos adicionar os métodos GET e POST.

Vamos então editar o nosso ficheiro ‘index.js’ e criar uma route para o ‘/edit/:id’.

Código:

var ObjectId = require('mongodb').ObjectID;//EDIT
app.route('/edit/:id')
.get((req,res) => {
var id = req.params.id;
db.find(ObjectId(id)).toArray((err, result) => {
if (err) return console.log("Error: " + err);
res.render('edit.ejs', { books: result });
});
})
.post((req,res) => {
var id = req.params.id;
var title = req.body.title;
var author = req.body.author;
var genre = req.body.genre;
db.updateOne({_id: ObjectId(id)}, {
$set: {
title: title,
author: author,
genre: genre
}
}, (err, result) => {
if (err) return res.send(err);
res.redirect('/show');
console.log("Registo atualizado com sucesso!");
})
});

Vamos agora criar o template engine dentro do diretório ‘views’ com o nome “edit.ejs”.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Books Repository</title>
</head>
<body>
<h2>Edit</h2>
<% books.forEach(function(details) { %>
<form action="/edit/<%= details._id %>" method="POST">
<input type="text" value="<%= details.title %>" name="title">
<input type="text" value="<%= details.author %>" name="author">
<input type="text" value="<%= details.genre %>" name="genre">
<br />
<button><a href="/show">List All</a></button>
<button type="submit">Edit</button>
</form>
<% }) %>
</body>
</html>

Vamos testar a opção ‘Edit’.

Aceda a http://localhost:3001 e edite o primeiro registo.

Se tudo correr bem, deverá aparecer na consola a mensagem de sucesso:

5. Eliminar dados — DELETE

A operação Delete é a mais simples de todas. A única coisa que temos de fazer é chamar o método deleteOne() e passar por parâmetro o id do objeto que queremos eliminar.

Vamos adicionar a route(/delete/:id) ao nosso ficheiro index.js

//DELETE
app.route('/delete/:id')
.get((req,res) => {
var id = req.params.id;
db.deleteOne({_id: ObjectId(id)}, (err, result) => {
if (err) return res.send(500, err);
console.log("Registo eliminado com sucesso!");
res.redirect('/show');
});
});

De forma a testar a funcionalidade DELETE, vamos inserir um novo registo e depois eliminá-lo. Se tudo correr bem, deve obter os seguintes resultados:

Inserir Registo
Lista atualizada

Após clicar no botão ‘Delete’:

E pronto, chegámos ao fim. Todo o código aqui descrito está disponível no Github. Já vimos que foi relativamente rápido fazer uma aplicação CRUD utilizando Node.js e MongoDB, agora cabe a cada um de nós ter ideias e colocá-las em prática!

Referência: https://medium.com/baixada-nerd/criando-um-crud-completo-com-nodejs-express-e-mongodb-parte-1-3-6c8389d7147d

--

--