Atualizado: 02/01/2025

Express e Mongoose - Node.js

Vamos explorar como integrar Mongoose e Express para realizar operações com dados quando o servidor recebe determinadas solicitações. Para isso, definimos o seguinte arquivo de aplicação, app.js:

const mongoose = require("mongoose");
const express = require("express");
const Schema = mongoose.Schema;
const app = express();
  
app.use(express.static("public"));
app.use(express.json());
    
const userScheme = new Schema({name: String, age: Number}, {versionKey: false});
const User = mongoose.model("User", userScheme);
  
async function main() {
    try {
        await mongoose.connect("mongodb://127.0.0.1:27017/usersdb");
        app.listen(3000);
        console.log("Servidor aguardando conexão...");
    } catch(err) {
        console.log(err);
    }
}
  
app.get("/api/users", async (req, res) => {
    // obtém todos os usuários
    const users = await User.find({});
    res.send(users);
});
  
app.get("/api/users/:id", async(req, res) => {
    const id = req.params.id;
    // obtém um usuário pelo id
    const user = await User.findById(id);
    if(user) res.send(user);
    else res.sendStatus(404);
});
      
app.post("/api/users", async (req, res) => {
    if(!req.body) return res.sendStatus(400);
          
    const userName = req.body.name;
    const userAge = req.body.age;
    const user = new User({name: userName, age: userAge});
    // salva no banco de dados
    await user.save();
    res.send(user);
});
      
app.delete("/api/users/:id", async(req, res) => {
    const id = req.params.id;
    // remove pelo id 
    const user = await User.findByIdAndDelete(id);
    if(user) res.send(user);
    else res.sendStatus(404);
});
      
app.put("/api/users", async (req, res) => {
    if(!req.body) return res.sendStatus(400);
    const id = req.body.id;
    const userName = req.body.name;
    const userAge = req.body.age;
    const newUser = {age: userAge, name: userName};
    // atualiza os dados do usuário pelo id
    const user = await User.findOneAndUpdate({_id: id}, newUser, {new: true}); 
    if(user) res.send(user);
    else res.sendStatus(404);
});
  
main();

// escuta a interrupção do programa (ctrl-c)
process.on("SIGINT", async() => {
    await mongoose.disconnect();
    console.log("Aplicação encerrada");
    process.exit();
});

Basicamente, todas as operações discutidas anteriormente são realizadas aqui. O único ponto a destacar é que o servidor é iniciado após a conexão bem-sucedida com o banco de dados usersdb na função mongoose.connect:

await mongoose.connect("mongodb://127.0.0.1:27017/usersdb");
app.listen(3000);
console.log("Servidor aguardando conexão...");

Agora, criamos uma nova pasta chamada public dentro do diretório do projeto e defina um arquivo index.html dentro desse diretório:

mongoapp/
│
├── node_modules/
│
├── public/
│   └── index.html
│
├── app.js
├── package.json
└── package-lock.json 

No arquivo index.html, definimos o seguinte código:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Programício</title>
    <style>
    td, th {padding: 5px; min-width: 90px; max-width: 200px; text-align: start;}
    .btn {padding: 4px; border: 1px solid #333; background-color: #eee; border-radius: 2px; margin: 5px; cursor: pointer;}
    </style>
</head>
<body>
<h2>Lista de Usuários</h2>
<form name="userForm">
    <input type="hidden" name="id" value="0" />
    <p>
        <label>Nome:</label><br>
        <input name="name" />
    </p>
    <p>
        <label>Idade:</label><br>
        <input name="age" type="number" />
    </p>
    <p>
        <button id="submitBtn" type="submit">Salvar</button>
        <button id="resetBtn">Redefinir</button>
    </p>
</form>
<table>
    <thead><tr><th>Id</th><th>Nome</th><th>Idade</th><th></th></tr></thead>
    <tbody></tbody>
</table>
<script>
const tbody = document.querySelector("tbody");

// Obtenção de todos os usuários
async function getUsers() {
    // envia a solicitação e recebe a resposta
    const response = await fetch("/api/users", {
        method: "GET",
        headers: { "Accept": "application/json" }
    });
    // se a solicitação foi bem-sucedida
    if (response.ok === true) {
        // obtém os dados
        const users = await response.json();
        users.forEach(user => {
            // adiciona os elementos recebidos à tabela
            tbody.append(row(user));
        });
    }
}

// Obtenção de um único usuário
async function getUser(id) {
    const response = await fetch("/api/users/" + id, {
        method: "GET",
        headers: { "Accept": "application/json" }
    });
    if (response.ok === true) {
        const user = await response.json();
        const form = document.forms["userForm"];
        form.elements["id"].value = user._id;
        form.elements["name"].value = user.name;
        form.elements["age"].value = user.age;
    }
}

// Adição de um novo usuário
async function createUser(userName, userAge) {
    const response = await fetch("api/users", {
        method: "POST",
        headers: { "Accept": "application/json", "Content-Type": "application/json" },
        body: JSON.stringify({
            name: userName,
            age: parseInt(userAge, 10)
        })
    });
    if (response.ok === true) {
        const user = await response.json();
        reset();
        tbody.append(row(user));
    }
}

// Edição de um usuário existente
async function editUser(userId, userName, userAge) {
    const response = await fetch("api/users", {
        method: "PUT",
        headers: { "Accept": "application/json", "Content-Type": "application/json" },
        body: JSON.stringify({
            id: userId,
            name: userName,
            age: parseInt(userAge, 10)
        })
    });
    if (response.ok === true) {
        const user = await response.json();
        reset();
        document.querySelector(`tr[data-rowid="${user._id}"]`).replaceWith(row(user));
    }
}

// Remoção de um usuário
async function deleteUser(id) {
    const response = await fetch("/api/users/" + id, {
        method: "DELETE",
        headers: { "Accept": "application/json" }
    });
    if (response.ok === true) {
        const user = await response.json();
        document.querySelector(`tr[data-rowid="${user._id}"]`).remove();
    }
}
    
// Redefinição do formulário
function reset() {
    const form = document.forms["userForm"];
    form.reset();
    form.elements["id"].value = 0;
}

// Criação de uma linha para a tabela
function row(user) {
    const tr = document.createElement("tr");
    tr.setAttribute("data-rowid", user._id);
        
    const idTd = document.createElement("td");
    idTd.append(user._id);
    tr.append(idTd);
        
    const nameTd = document.createElement("td");
    nameTd.append(user.name);
    tr.append(nameTd);
        
    const ageTd = document.createElement("td");
    ageTd.append(user.age);
    tr.append(ageTd);
        
    const linksTd = document.createElement("td");
        
    const editLink = document.createElement("a");
    editLink.setAttribute("data-id", user._id);
    editLink.setAttribute("class", "btn");
    editLink.append("Editar");
    editLink.addEventListener("click", e => {
        e.preventDefault();
        getUser(user._id);
    });
    linksTd.append(editLink);
        
    const removeLink = document.createElement("a");
    removeLink.setAttribute("data-id", user._id);
    removeLink.setAttribute("class", "btn");
    removeLink.append("Remover");
    removeLink.addEventListener("click", e => {
        e.preventDefault();
        deleteUser(user._id);
    });
        
    linksTd.append(removeLink);
    tr.appendChild(linksTd);
        
    return tr;
}

// Redefinição dos valores do formulário
document.getElementById("resetBtn").addEventListener("click", e => {
    e.preventDefault();
    reset();
});
    
// Envio do formulário
document.forms["userForm"].addEventListener("submit", e => {
    e.preventDefault();
    const form = document.forms["userForm"];
    const id = form.elements["id"].value;
    const name = form.elements["name"].value;
    const age = form.elements["age"].value;
    if (id == 0)
        createUser(name, age);
    else
        editUser(id, name, age);
});
    
// Carregamento dos usuários
getUsers();
</script>
</body>
</html>

O código no arquivo index.html foi discutido resumidamente no tema sobre criação de API em Node.js; aqui, o código é praticamente repetido.

Como o Express utiliza a pasta public como armazenamento de arquivos estáticos, ao acessar a aplicação pela rota raiz http://localhost:3000, o cliente receberá este arquivo.

Iniciamos a aplicação e acesse-a pelo endereço http://localhost:3000. Assim, podemos interagir com o banco de dados MongoDB através do Mongoose:

Express e Mongoose para trabalhar com o banco de dados MongoDB em uma aplicação Node.js
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com