MongoDB + Node
Tags: beginners, mongodb, typescript, braziliandevs
Published: 2022-11-03 14:28:47

## Tabela de Conteúdo

- [Mongoose](#mongoose)
- [URI](#uri)
- [Schemas](#schemas)
- [Models](#models)
- [Links Úteis](#links-úteis)

---

## Mongoose

### O que é?

O Mongoose é uma ferramenta de integração entre Node.js e MongoDB, tendo um funcionamento similar a ORMs, com a principal diferença de trabalhar com um DB NoSQL ao invés de um relacional, devido a isso ele é classificado como ODM _(Object Document Mapping)_.

### O que faz?

Como dito em sua definição, o Mongoose facilita a integração entre API e DB, para isso ele conta com diversos recursos que _"rodam por baixo dos panos"_, porém um recurso explicito que vale a pena detalhar são os `Schemas`.

Os `Schemas` serão abordados mais a frente, mas o que vale a apena destacar é sua funcionamento, eles atuam de forma similar a uma _"tipagem"_ para os Documentos do MongoDB, dessa forma podemos garantir um padrão nas Coleções.


### Instalação

Para utilizarmos o Mongoose em nossos projetos primeiro devemos instalá-lo como uma dependência, após ter feito sua instalação tudo que precisamos fazer é conectá-lo a nossa aplicação.

Para conectar a aplicação ao MongoDB através do Mongoose devemos utilizar o método `connect` disponibilizado pela própria biblioteca, passando a [URI](https://mongoosejs.com/docs/connections.html) como primeiro parâmetro e como segundo podemos passar algumas opções de conexão, essas que são optativas.

``` bash
npm i mongoose
```

``` ts
import { connect } from 'mongoose';

connect('mongodb://localhost:27017/my_db', { user: 'admin', password: 'admin' });
```

<br />

<small>[Voltar ao topo](#tabela-de-conteúdo)</small>

---

## URI

### O que é?

É a sigla para _Uniforme Resource Identifier_, traduzindo, _Identificador de Recurso Único_.

Em palavras mais simples, é uma _string_ que irá conter as informações necessárias para a conexão com o DB, esse que pode ser SQL ou NoSQL.

### Sintaxe

A URI padrão do MongoDB consiste em: nome de usuário; dois pontos `:`; senha; arroba `@`; e então as informação de conexão, host e porta. Porém esse padrão não é o mais recomendado para se utilizar no Mongoose, afinal não seria nada inteligente deixar o usuário e a senha expostos em _hard code_.

No Mongoose podemos utilizar apenas os dados de conexão _(host e porta)_ e o nome do banco de dados a ser conectado, assim passamos o usuário e senha através de um objeto no segundo parâmetro do método `connect` visto logo acima.

*Obs: _As URIs sempre irão começar com `mongodb://`_.

``` ts
// URI padrão do MongoDB

connect('mongodb://<nome de usuário>:<senha>@<host>:<porta>/<nome do db>');
connect('mongodb://admin:admin@localhost:27017/my_db');
```

``` ts
// URI do Mongoose com options

connect('mongodb://<host>:<porta>/<nome do db>', { user: '<nome de usuário>', password: '<senha>' });
connect('mongodb://localhost:27017/my_db', { user: 'admin', password: 'admin' });
```

**Obs: _No exemplo acima estamos colocando o usuário e a senha também em "hard code" nas options do `connect`, porém isso é apenas a caráter de exemplificação, __o correto seria utilizar variáveis de ambiente__ para ambas as informações_

<br />

<small>[Voltar ao topo](#tabela-de-conteúdo)</small>

---

## Schemas

### O que são?

São as estruturas básicas de um Documento MongoDB em nosso código TypeScript, dessa forma conseguimos mapear de forma eficiente todos os campos e por consequência melhorar a experiência de desenvolvimento.

### O que fazem?

Os Schemas mapeiam os Documentos de uma coleção, facilitando a interação sobre os Documentos dentro do código da aplicação.

### Sintaxe

Para definirmos um Schema utilizamos o construtor `new Schema` disponibilizado pelo próprio Mongoose, passando como Generic a interface que representa a estrutura do Documento.

``` ts
import { Schema } from 'mongoose';

new Schema</* generic */>({
  /* nome do campo */: { type: /* tipo do campo */, required: /* true ou false */ },
  /* nome do campo */: { type: /* tipo do campo */, required: /* true ou false */ },
});
```

``` ts
import { Schema } from 'mongoose';

interface IUser {
  username: string;
  email: string;
  password: string;
}

const userSchema = new Schema<IUser>({
  username: { type: String, required true },
  email: { type: String, required true },
  password: { type: String, required true },
});
```

Obs: _Podemos passar outros dois Generics para o `Schema`, sendo eles a `Model` e os `TInstanceMethods` respectivamente, porém não iremos abordar eles aqui_.

<br />

<small>[Voltar ao topo](#tabela-de-conteúdo)</small>

---

## Models

### O que são?

No contexto do Mongoose as Models, assim como os Schemas, contém a estrutura básica de um Documento, mas além disso elas também nos disponibilizam métodos para que possamos interagir com os Documentos dentro de uma Coleção.

### O que fazem?

Como dito em sua definição, as Models nos disponibilizam métodos para que possamos interagir com os Documentos, dessa forma conseguimos adicionar, atualizar, excluir e ler dados contidos nos Documentos de forma fácil.

### Sintaxe

Para definir uma Model utilizamos a função `model()` disponibilizada pelo Mongoose, passando como _Generic_ a interface que representa aquele documento, já como parâmetros passamos o nome da coleção e o `Schema` do Documento.

``` ts
import { Schema, model } from 'mongoose';

interface /* Nome do documento */ {
  /* nome do campo */: /* tipo do campo */;
  /* nome do campo */: /* tipo do campo */;
  /* nome do campo */: /* tipo do campo */;
}

const /* nome do schema */ = new Schema</* interface */>({
  /* nome do campo */: { type: /* tipo do campo */, required: /* true ou false */ },
  /* nome do campo */: { type: /* tipo do campo */, required: /* true ou false */ },
});

const /* nome da model */ = model</* interface */>(/* nome da coleção */, /* schema */);
```

``` ts
import { Schema, model } from 'mongoose';

interface IUser {
  username: string;
  email: string;
  password: string;
}

const userSchema = new Schema<IUser>({
  username: { type: String, required true },
  email: { type: String, required true },
  password: { type: String, required true },
});

const userModel = model<IUser>('users', userSchema);
```

*Obs: _Não iremos abordar nenhum método das Models aqui, porém a sessão [Links Úteis](#links-úteis) irá conter um link direcionado diretamente a essa parte da documentação_.

<br />

<small>[Voltar ao topo](#tabela-de-conteúdo)</small>

---

## Links Úteis

- [Documentação Mongoose](https://mongoosejs.com/docs/guide.html)
- [Mongoose com TypeScript](https://mongoosejs.com/docs/typescript.html)
- [Mongoose - Connections Guide](https://mongoosejs.com/docs/connections.html)
- [Mongoose - Schemas Guide](https://mongoosejs.com/docs/guide.html)
- [Mongoose - Models Guide](https://mongoosejs.com/docs/models.html)
- [Mongoose - Queries Guide](https://mongoosejs.com/docs/queries.html)

<br />

<small>[Voltar ao topo](#tabela-de-conteúdo)</small>