O Node trabalha com pequenas bibiotecas ao invés de grandes frameworks.
Formas de conectar o Node com o Banco de Dados
- ORM - Object-Relational Mapping
O mapeamento objeto-relacional (ORM ou MOR) é uma técnica muito utilizada para converter dados entre sistemas de tipos incompatíveis, como por exemplo, bancos relacionais e linguagens orientadas a objeto. Isso cria, com efeito, um "banco de dados de objetos virtuais" que pode ser usado a partir da linguagem de programação.
- Drivers Nativos
Cada banco de dados tem o seu, e é a maneira mais simples.
Formas de abrir uma conexão
- Conexão Direta
Não recomendado: Basicamente cria-se uma instância que cria uma conexão para cada chamada.
- Conexão através de Pool de Conexões
Recomendado: Usar pool de conexões (em produção) para evitar o bloqueio de conexões.
Mais flexível.
Banco de Dados PostgreSQL Cloud (ElephantSQL)
elephantsql.com
Para executar os scripts ir na opção Browser.
Biblioteca node-postgres.com
Driver Nativo. Cliente PostgreSQL sem bloqueio para Node.js. JavaScript puro e ligações nativas opcionais.
Instalar Biblioteca node-postgres.com como dependência de projeto.
npm install pg
@types do TypeScript para a biblioteca node-postgres.com
Instalar como dependência de desenvolvimento do projeto.
npm install --save-dev @types/pg
Configuração do Pool de Conexões
Há duas formas de configurar a conexão com o banco de dados.
- Dados separados: host, port, user, password, database
- Conncetion string: arquivo src/bd.ts
import { Pool } from 'pg';
const connectionString = 'postgres://localhost:5432/postgres';
const db = new Pool({ connectionString });
export default db;
Configuração das Variáveis de Ambiente
Permite escrever programas sem ter que especificar informações de conexão e permite reutilizá-los para conectar-se a bancos de dados diferentes sem ter que modificar o código.
Ao instanciar o Pool de Conexões, ele já busca por padrão as variáveis de ambiente.
The default values for the environment variables used are:
PGHOST='localhost'
PGUSER=process.env.USER
PGDATABASE=process.env.USER
PGPASSWORD=null
PGPORT=5432
Recomendação:
Quando for um projeto Standalone, deixar os scripts sql junto da aplicação.
Criação da Tabela de Usuário e Inserção de um Usuário
Criar o arquivo sql/init.sql na raiz do projeto.
Facilita caso seja usado Docker ou seja necessário criar um novo environment.
/* Habilita extensão para executar uma função que gera um hash */
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
/* Habilita extensão para executar uma função que gera um dado criptografado */
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
/*
Criação da tabela de usuário.
Será usado um hash para o id, ao invés de um id incremental
*/
CREATE TABLE IF NOT EXISTS users (
uuid uuid DEFAULT uuid_generate_v4(),
userName VARCHAR NOT NULL,
userEmail VARCHAR NOT NULL,
userPassword VARCHAR NOT NULL,
PRIMARY KEY (uuid)
)
/* Inserir o usuário admin */
INSERT INTO users (userName, userEmail, userPassword)
VALUES ('admin', 'heviane@gmail.com', crypt('admin', 'my_salt'));
A utilização de um hash é mais segura do que um id incremental, porque remove a previsibilidade do sequencial e evita possível mineração em cima da base de dados.
Criação dos campos de Usuário (Model)
Estrutura src/models/user.model.ts
Os campos podem ser:
- Type: É apenas uma definição de como deve ser o objeto.
- Interface: Pode ter várias implementações de uma interface.
- Classe: Pode ser instanciada ou extendida.
type User = {
uuid?: string; // ? = Opcional
userName: string;
userEmail: string;
userPassword?: string; // ? = Opcional
}
export default User;