> For the complete documentation index, see [llms.txt](https://salvatore-academy.gitbook.io/dev-fullstack-web/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://salvatore-academy.gitbook.io/dev-fullstack-web/academia/missoes-de-backend/mongodb-intro-e-implementacao.md).

# MongoDB: Intro e Implementação

{% hint style="info" %}
Desenvolva habilidades com o MongoDB, um banco de dados NoSQL líder, e aprenda a realizar o deploy de um banco de dados na nuvem usando o MongoDB Cloud Atlas. Esta etapa é essencial para preparar o ambiente para integração com aplicações hospedadas em plataformas de cloud, como o CodeSpaces.
{% endhint %}

## Vídeo

{% embed url="<https://youtu.be/Csk1U5b-uuI>" %}

**Link direto:** <https://youtu.be/Csk1U5b-uuI>

## Tópicos

1. **Introdução ao MongoDB:**
   * Explanação sobre bancos de dados NoSQL e o ecossistema do MongoDB.
   * Instalação do MongoDB Compass e introdução às suas funcionalidades.
2. **Deploy no MongoDB Cloud Atlas:**
   * Criação de uma conta no MongoDB Cloud Atlas.
   * Configuração do cluster MongoDB no Cloud Atlas.
   * Conexão do MongoDB Compass com o banco de dados no Cloud Atlas.
3. **CRUD com MongoDB:**
   * Execução de operações CRUD utilizando o MongoDB Compass conectado ao Cloud Atlas.
   * Integração do MongoDB Cloud Atlas com o projeto backend Node.js.

## Material de Apoio

### Repositório no GitHub

{% embed url="<https://github.com/SalvatoreAcademy/backend-missao-aprendizado-iniciante-mongodb-intro-e-implementacao>" %}

### PDF para Download

{% file src="/files/qH03EAgOyYoSAwCiCbRk" %}

### Miro

{% embed url="<https://miro.com/app/board/uXjVNQ6PZjQ=/?moveToWidget=3458764587647670381&cot=14>" %}

## Exercícios de Fixação

{% hint style="info" %}
Use esses exercícios para reforçar o que acabou de aprender. Se errar, leia a explicação para entender melhor o conceito.
{% endhint %}

<details>

<summary>Qual comando usamos para instalar o MongoDB Driver no Node.js?</summary>

A) `npm install mongodb`

B) `npm install mongoose`

C) `npm install mongo`

D) `npm install mongodriver`

</details>

<details>

<summary>Resposta correta</summary>

**Qual comando usamos para instalar o MongoDB Driver no Node.js?**

**Resposta Correta**: A

**Feedback**: O comando `npm install mongodb` é usado para instalar o driver oficial do MongoDB para Node.js.

</details>

***

<details>

<summary>Complete o código para conectar ao MongoDB usando o MongoClient, inicializar o banco de dados e exibir uma mensagem de sucesso.</summary>

{% code lineNumbers="true" %}

```javascript
const { MongoClient } = require('mongodb');
const dbUrl = 'mongodb+srv://<user>:<password>@cluster0.mongodb.net';
const client = new MongoClient(dbUrl);

async function main() {
  await client._________();
  const db = client.db('testdb');
  console.log('Banco de dados conectado com sucesso!');
}

main();
```

{% endcode %}

</details>

<details>

<summary>Resposta correta</summary>

**Complete o código para conectar ao MongoDB usando o MongoClient.**

**Resposta Correta**:

```javascript
await client.connect();
```

**Feedback**: O método `connect` é usado para estabelecer a conexão com o banco de dados, e a mensagem `Banco de dados conectado com sucesso!` é exibida após a conexão ser bem-sucedida.

</details>

***

<details>

<summary>Verdadeiro ou Falso: O MongoDB é um banco de dados relacional.</summary>

A) Verdadeiro

B) Falso

</details>

<details>

<summary>Resposta correta</summary>

**Verdadeiro ou Falso: O MongoDB é um banco de dados relacional.**

**Resposta Correta**: B

**Feedback**: O MongoDB é um banco de dados NoSQL, não relacional, que armazena dados em documentos JSON-like.

</details>

***

<details>

<summary>Qual comando usamos para iniciar a aplicação com Nodemon?</summary>

A) `npm start`

B) `npm run start`

C) `npm run dev`

D) `nodemon app.js`

</details>

<details>

<summary>Resposta correta</summary>

**Qual comando usamos para iniciar a aplicação com Nodemon?**

**Resposta Correta**: C

**Feedback**: O comando `npm run dev` é comumente usado para iniciar a aplicação com Nodemon, conforme configurado no `package.json`.

</details>

***

<details>

<summary>Complete o código para criar um endpoint que adicione um novo documento à collection no MongoDB.</summary>

{% code lineNumbers="true" %}

```javascript
const express = require("express");
const { MongoClient } = require("mongodb");
const app = express();
app.use(express.json());

const dbUrl = 'mongodb+srv://<user>:<password>@cluster0.mongodb.net';
const client = new MongoClient(dbUrl);

async function main() {
  await client.connect();
  const db = client.db('testdb');
  const collection = db.collection('personagens');

  app.post("/personagem", async function (req, res) {
    const novoItem = req.body;
    if (!novoItem.nome) {
      return res.status(400).send('Corpo da requisição deve conter a propriedade nome.');
    }

    await collection._________(novoItem);
    res.status(201).send(novoItem);
  });

  app.listen(3000, function () {
    console.log("Aplicação rodando em http://localhost:3000");
  });
}

main();
```

{% endcode %}

</details>

<details>

<summary>Resposta correta</summary>

**Complete o código para criar um endpoint que adicione um novo documento à collection no MongoDB.**

**Resposta Correta**:

```javascript
await collection.insertOne(novoItem);
```

**Feedback**: O método `insertOne` é usado para adicionar um novo documento à collection do MongoDB.

</details>

## Exercícios de Validação

{% hint style="info" %}
Esses exercícios testarão sua compreensão prática. Revise o feedback para melhorar suas habilidades.
{% endhint %}

### Desafio de Código

Crie um endpoint adicional na aplicação ExpressJS que atualize um documento existente na collection do MongoDB. Se o documento não existir, o endpoint deve responder com "Item não encontrado".

* Implementar o novo endpoint no arquivo `index.js`.

<details>

<summary>Resposta esperada</summary>

{% code lineNumbers="true" %}

```javascript
app.put("/personagem/:id", async function (req, res) {
  const id = req.params.id;
  const novoItem = req.body;

  if (!novoItem.nome) {
    return res.status(400).send('Corpo da requisição deve conter a propriedade nome.');
  }

  const resultado = await collection.updateOne({ _id: new ObjectId(id) }, { $set: novoItem });

  if (resultado.matchedCount === 0) {
    return res.status(404).send('Item não encontrado.');
  }

  res.send('Item atualizado com sucesso.');
});
```

{% endcode %}

**Feedback:** Certifique-se de que o servidor está ouvindo na porta correta e que a rota `/personagem/:id` está devidamente configurada.

</details>

### Revisão de Código

{% hint style="danger" %}
**Analise o código a seguir, encontre e corrija o erro.**
{% endhint %}

{% code lineNumbers="true" %}

```javascript
const express = require("express");
const { MongoClient, ObjectId } = require("mongodb");
const app = express();

const dbUrl = 'mongodb+srv://<user>:<password>@cluster0.mongodb.net';
const client = new MongoClient(dbUrl);

const db = client.db('biblioteca');
const collection = db.collection('livros');

app.use(express.json());

app.get("/livros/:id", async function (req, res) {
  const id = req.params.id;
  const livro = await collection.findOne({ _id: id });

  if (!livro) {
    return res.status(404).send('Livro não encontrado.');
  }

  res.send(livro);
});

app.listen(3000, function () {
  console.log("Aplicação rodando em http://localhost:3000");
});
```

{% endcode %}

<details>

<summary>Resposta Correta</summary>

**Erros:**

1. Conexão com o banco de dados MongoDB não é estabelecida.
2. O ID do livro não é convertido para `ObjectId` ao buscar o documento.

{% code lineNumbers="true" %}

```javascript
const express = require("express");
const { MongoClient, ObjectId } = require("mongodb");
const app = express();

const dbUrl = 'mongodb+srv://<user>:<password>@cluster0.mongodb.net';
const client = new MongoClient(dbUrl);

app.use(express.json());

async function main() {
  await client.connect();
  const db = client.db('biblioteca');
  const collection = db.collection('livros');

  app.get("/livros/:id", async function (req, res) {
    const id = req.params.id;
    const livro = await collection.findOne({ _id: new ObjectId(id) });

    if (!livro) {
      return res.status(404).send('Livro não encontrado.');
    }

    res.send(livro);
  });

  app.listen(3000, function () {
    console.log("Aplicação rodando em http://localhost:3000");
  });
}

main();
```

{% endcode %}

**Feedback**: Certifique-se de que a conexão com o banco de dados MongoDB está estabelecida antes de acessar o banco de dados e a collection. Além disso, converta corretamente o ID do livro para `ObjectId` ao buscar o documento.

</details>

### Projeto Prático

Implemente um CRUD completo para gerenciar uma entidade de "Livros" em uma biblioteca usando ExpressJS e MongoDB. Os livros devem ter as propriedades "título", "autor" e "ano de publicação". Crie endpoints para adicionar, listar, atualizar e deletar livros. Se o livro não for encontrado, o endpoint deve responder com "Livro não encontrado".

#### Tarefas

* **Configuração Inicial**:
  * Inicialize um novo projeto NodeJS.
  * Instale o ExpressJS e o MongoDB Driver.
  * Configure o Nodemon para reiniciar o servidor automaticamente.
* **Conexão com o MongoDB**:
  * Conecte-se ao MongoDB utilizando o MongoClient.
  * Inicialize o banco de dados e a collection "livros".
* **Implementação dos Endpoints**:
  * Implemente um endpoint para adicionar um novo livro (`POST /livros`).
  * Implemente um endpoint para listar todos os livros (`GET /livros`).
  * Implemente um endpoint para obter um livro específico por ID (`GET /livros/:id`).
  * Implemente um endpoint para atualizar um livro por ID (`PUT /livros/:id`).
  * Implemente um endpoint para deletar um livro por ID (`DELETE /livros/:id`).

<details>

<summary>Código esperado</summary>

{% code title="index.js" lineNumbers="true" %}

```javascript
const express = require("express");
const { MongoClient, ObjectId } = require("mongodb");
const app = express();
app.use(express.json());

const dbUrl = 'mongodb+srv://<user>:<password>@cluster0.mongodb.net';
const client = new MongoClient(dbUrl);

async function main() {
  await client.connect();
  const db = client.db('biblioteca');
  const collection = db.collection('livros');

  // Endpoint para adicionar um novo livro
  app.post("/livros", async function (req, res) {
    const novoLivro = req.body;

    if (!novoLivro.titulo || !novoLivro.autor || !novoLivro.anoPublicacao) {
      return res.status(400).send('Corpo da requisição deve conter as propriedades título, autor e ano de publicação.');
    }

    await collection.insertOne(novoLivro);
    res.status(201).send(novoLivro);
  });

  // Endpoint para listar todos os livros
  app.get("/livros", async function (req, res) {
    const livros = await collection.find().toArray();
    res.send(livros);
  });

  // Endpoint para obter um livro específico por ID
  app.get("/livros/:id", async function (req, res) {
    const id = req.params.id;
    const livro = await collection.findOne({ _id: new ObjectId(id) });

    if (!livro) {
      return res.status(404).send('Livro não encontrado.');
    }

    res.send(livro);
  });

  // Endpoint para atualizar um livro por ID
  app.put("/livros/:id", async function (req, res) {
    const id = req.params.id;
    const novoLivro = req.body;

    if (!novoLivro.titulo || !novoLivro.autor || !novoLivro.anoPublicacao) {
      return res.status(400).send('Corpo da requisição deve conter as propriedades título, autor e ano de publicação.');
    }

    const resultado = await collection.updateOne({ _id: new ObjectId(id) }, { $set: novoLivro });

    if (resultado.matchedCount === 0) {
      return res.status(404).send('Livro não encontrado.');
    }

    res.send('Livro atualizado com sucesso.');
  });

  // Endpoint para deletar um livro por ID
  app.delete("/livros/:id", async function (req, res) {
    const id = req.params.id;
    const resultado = await collection.deleteOne({ _id: new ObjectId(id) });

    if (resultado.deletedCount === 0) {
      return res.status(404).send('Livro não encontrado.');
    }

    res.send('Livro deletado com sucesso.');
  });

  app.listen(3000, function () {
    console.log("Aplicação rodando em http://localhost:3000");
  });
}

main();
```

{% endcode %}

**Feedback Detalhado**

* **Verificação dos Endpoints**: Certifique-se de testar cada rota (`/livros`, `/livros/:id`, `/livros` com POST, PUT e DELETE) acessando `http://localhost:3000` e verificando as respostas.
* **Estrutura**: A estrutura básica da aplicação deve seguir a mesma lógica apresentada na missão original.
* **Diferença Sutil**: A inclusão da entidade "Livros" oferece um exercício prático de aplicação do conhecimento adquirido, sem introduzir novos conceitos.

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://salvatore-academy.gitbook.io/dev-fullstack-web/academia/missoes-de-backend/mongodb-intro-e-implementacao.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
