Skip to content

Instantly share code, notes, and snippets.

@oleoprado
Last active March 20, 2023 19:41
Show Gist options
  • Select an option

  • Save oleoprado/a8090431f7d71313bb52cbfe8d72a7fa to your computer and use it in GitHub Desktop.

Select an option

Save oleoprado/a8090431f7d71313bb52cbfe8d72a7fa to your computer and use it in GitHub Desktop.
APIs Orientadas a Objeto e NoSQL

Mongoose

  • ODMs (Object Document Mapping), que lidam com dados estruturados em bancos de dados não relacionais (como o MongoDB, DynamoDB, entre outros).

O Mongoose consiste em uma implementação de ODM para aplicações desenvolvidas em Node.Js, com vistas a remover a complexidade na interação com o MongoDB. Para isso, são definidos Schemas e Models para cada Collection no banco de dados.

  • Defina um Schema para uma Collection, uma espécie de molde para os documentos que serão armazenados. O Schema será usado para construção da Model de uma coleção, que proverá toda a lógica necessária para o acesso, armazenamento e manipulação dos documentos.

Instalação e configuração Mongoose

  • Instalar o pacote:
npm install -E mongoose@6.1.8
  • Criar um arquivo connection.ts e colocar o código:
import { connect } from 'mongoose'

  const options = {
  user: 'user', // Usuário do banco de dados.
  pass: 'password', // senha do usuário do banco de dados.
  dbName: 'trixDB', // Define qual banco de dados você irá utilizar.
};

connect('mongodb://localhost:27017/', options);

No trecho de código acima, para fazermos uma conexão ao MongoDB, usando o Mongoose, apenas utilizamos o método connect(), passando a URI (Uniform Resource Identifier) do banco para nos conectar e a variável options com as nossas configurações.


Schemas e Models

Paradigma de programação prodecural

import { Schema } from 'mongoose';

const petSchema = new Schema({
  name: { type: String, required: true },
  species: { type: String, required: true },
  age: { type: Number, required: false },
  weight: { type: Number, required: true },
  dailyMealsNumber: { type: Number, required: true, min: 2, max: 5 },
});

  const Pet = model('Pet', petSchema);

O Mongoose fornece diferente tipos de dados para os Schemas, tais como:

  • String
  • Number
  • Date
  • Boolean
  • ObjectId
  • Array

A função model(), cria uma Model para uma Collection. Essa função recebe como parâmetros, e nessa ordem, uma String contendo o nome da Collection e o Schema com o “molde” que definimos anteriormente.

Na primeira vez que essa Model for utilizada, o Mongoose se encarregará de criar toda a estrutura no MongoDB, ou seja, se a Collection ainda não existir, o Mongoose irá criá-la no banco de dados.


Paradigma programação Orientada a Objetos

Primeiramente definir o Schema para nossa Collection. No entanto, para que seja possível fazer isso utilizando a orientação a objetos, precisaremos de dois conceitos muito importantes: as interfaces e os Generics.

As interfaces serão utilizadas como um contrato para o nosso Schema e para a Model.

import { Schema, model, connect } from 'mongoose';

// 1. Cria a interface que representa as informações de um Pet
interface IPet {
  name: string;
  species: string;
  age?: number; //Campo opcional definido por: (?)
  weight: number;
  dailyMealsNumber: number;
}

// 2. Cria o Schema de acordo com Interface por meio do Generic: <IPet>
const petSchema = new Schema<IPet>({
  name: { type: String, required: true },
  species: { type: String, required: true },
  age: { type: Number, required: false },
  weight: { type: Number, required: true },
  dailyMealsNumber: { type: Number, required: true, min: 2, max: 5 },
});

// 3. Cria a Model de acordo com a Interface e o Schema
const Pet = model<IPet>('Pet', petSchema); // Aceita somente schemas do tipo IPet

Enum

Uma enum é um nome simbólico para um conjunto de valores relacionados, o que significa que você pode utilizá-la para criar um conjunto de constantes para uso com variáveis e propriedades.

Imagine que você tem um campo em um banco de dados externo que representa o status de pagamento de uma pessoa por transferência instantânea, chamado PaymentStatus, que é do tipo inteiro e pode conter os números 1, 2 ou 3, que representam, respectivamente, Pending, Concluded e Reversed. Vamos criar uma enumeração com esses valores e entender como eles funcionam no TypeScript.

  enum PaymentStatus {
  pending,
  concluded,
  reversed,
}

Por padrão, uma enum é baseada em números. Os valores começam de zero e, para cada opção, é assinalado um número incrementado por 1, assim como os índices de um array. Portanto, Pending é 0, Concluded é 1 e Paused é 2. Para termos a nossa enum refletindo os valores que temos no banco de dados externo, precisamos declarar isso da seguinte forma:

enum PaymentStatus {
pending = 1,
concluded,
reversed,
}

Atribuir o número 1 para o primeiro valor da nossa enum já é o suficiente. Agora, quando imprimirmos a nossa variável newTransfer, o valor será 1 - como era esperado.

const newTransfer: PaymentStatus = PaymentStatus.pending;
console.log(newTransfer); // saída: 1

Enums suportam o acesso ao dado em ambas as direções: da chave ao valor e do valor à chave.

enum PaymentStatus {
pending = 1,
concluded = 2,
reversed = 3,
}

const pendingCode = PaymentStatus.pending;
const indexPending = PaymentStatus["pending"];
const stringReversed = PaymentStatus[3];

console.log(pendingCode); // saída: 1
console.log(indexPending); // saída: 1
console.log(stringReversed); // saída: reversed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment