Quando estamos construindo aplicações com bancos de dados, independente da linguagem, existem muitas, mas muitas atividades repetitivas mesmo entre sistemas completamente diferentes. Uma delas é a escrita dos comandos e consultas para fazer inserções, atualizações, etc nas tabelas do seu banco e a outra é o mapeamento das entidades e relacionamentos em objetos ou módulos da sua aplicação.
Mapear tabelas para código é um padrão muito comum independente de linguagem ou framework pois te permite programar mais próximo da regra de negócio da empresa, reduz a carga cognitiva de ficar chaveando mentalmente entre as diferentes camadas da aplicação e lhe dá muita produtividade, uma vez que, depois do mapeamento feito, atividades triviais, porém trabalhosas, como ficar escrevendo os mesmos comandos de sempre se tornam apenas simples chamadas de funções ou métodos.
Um ORM é um framework que lhe permite fazer este mapeamento de forma automática ou de forma manual, mas extremamente simplificada, como no caso do Prisma, um dos ORMs mais populares da atualidade. O Prisma, segundo o site oficial, é um ORM da próxima geração para Node.js baseado em TypeScript, para não apenas diversos bancos SQL como também para MongoDB. Entre suas principais características estão o suporte a transações sólidas (ACID), relacionamentos, eager e lazy loading (carregamento adiantado ou tardio), replicação de leitura e muito mais.
No tutorial de hoje vou lhe ensinar a como construir um CRUD utilizando Node.js e MySQL com o ORM Prisma, mas que pode ser usado para outros bancos SQL sem grandes alterações.
Atenção: este é um tutorial para quem já conhece Node.js. Se você não conhece esta tecnologia, comece por algo mais introdutório.
Atenção 2: usaremos TypeScript aqui, em virtude do Prisma ser focado nele. Se você não sabe nada de TS, comece por este tutorial.
Se preferir, você pode assistir ao vídeo abaixo, o conteúdo é o mesmo.
Vamos lá!
#1 – Ambiente
O primeiro passo é garantir que você tenha o Node.js instalado na sua máquina, nãoecessário para criar aplicações com JavaScript e TypeScript fora do browser. Pula este passo se já tiver ele instalado. Basta acessar Nodejs.org, baixar a versão LTS e instalar até o final. Caso tenha dificuldade, o vídeo abaixo ensina passo a passo.
O próximo passo é instalar o MySQL na sua máquina, que é o banco SQL que usarei aqui. Caso já tenha o MySQL instalado ou outro banco SQL qualquer, pule este passo. Para instalar o MySQL você deve baixar a versão Community no site oficial e instalar até o final, lembrando de anotar a senha root que você vai definir durante a instalação. Caso tenha qualquer dificuldade, use o passo a passo do vídeo abaixo.
Você vai precisar não apenas do server mas também do client gráfico, chamado MySQL Workbench que você pode baixar neste link, instalando até o final (só avançar). Depois de instalar, abra a ferramenta MySQL Workbench e crie um schema (banco de dados) novo, vou chamar o meu de ‘crud’.
Agora que você já tem o banco pronto, vamos criar uma tabela nele e colocar alguns dados de exemplo. Se você nunca criou um banco e uma tabela em sua vida, o vídeo abaixo é altamente recomendável.
Aqui usaremos uma tabela de clientes que você deve criar visualmente com o MySQL Workbench ou executando o SQL abaixo, que deve servir como linha guia para a criação visual também:
1 2 3 4 5 6 7 8 9 |
CREATE TABLE IF NOT EXISTS Clientes( ID int NOT NULL AUTO_INCREMENT, Nome varchar(150) NOT NULL, Idade int NOT NULL, UF char(2) NOT NULL, PRIMARY KEY (ID) ); |
Com banco e tabela preparados, adicione alguns clientes manualmente e podemos avançar para construção da aplicação.
#2 – Estruturando o Projeto
Agora indo ao que interessa, crie uma pasta para sua aplicação Node.js na sua máquina com npm init e instale as dependências que vamos precisar. A minha eu chamei de nodejs-prisma-mysql, nomeie a sua de acordo.
1 2 3 |
npm i -D typescript ts-node prisma |
Agora vamos inicializar o TypeScript no projeto com o comando abaixo.
1 2 3 |
npx tsc --init |
Crie um arquivo index.ts com um console.log qualquer e vamos ajustar o package.json para que inicialize o projeto com o TS Node e este arquivo que recém criamos.
1 2 3 4 5 |
"scripts": { "start": "ts-node index" }, |
Agora vamos falar de Prisma. Rode o comando abaixo para inicializar o Prisma neste projeto.
1 2 3 |
npx prisma init |
Isso vai criar uma pasta prisma com um schema.prisma (falaremos dele em breve) e um arquivo .env na raiz do projeto. Abra esse .env e preencha a variável DATABASE_URL com a connection string do seu banco SQL. Abaixo a minha relacionada com o MySQL, como exemplo.
1 2 3 |
DATABASE_URL="mysql://root:luiztools@localhost:3306/crud?schema=public" |
Agora abra seu prisma/schema.prisma e mude o provider para mysql.
1 2 3 4 5 6 7 8 9 10 |
generator client { provider = "prisma-client-js" } datasource db { provider = "mysql" url = env("DATABASE_URL") } |
Agora que configuramos o Prisma para conhecer onde está nosso banco, é hora de fazê-lo mapear nossas tabelas localmente. Fazemos isso com o comando abaixo.
1 2 3 |
npx prisma db pull |
Isso vai fazer com que todas tabelas existentes no banco (definido no .env) sejam mapeadas no schema.prisma, como no caso da users abaixo.
1 2 3 4 5 6 7 8 |
model clientes { id Int @id @default(autoincrement()) nome String? @db.VarChar(150) idade Int? uf String @db.VarChar(2) } |
Opcionalmente você poderia criar todo o seu banco a partir de um schema como esse, mas isto é algo que considero um pouco mais avançado, então deixarei para tutoriais futuros.
E por fim, agora você deve rodar o comando abaixo para gerar o Prisma Client.
1 2 3 |
npx prisma generate |
O Prisma Client é uma API gerada de maneira personalizada para o seu banco de dados e é com ele que vamos usar o Prisma de fato no projeto.
Importante sinalizar que toda vez que mexer no schema.prisma, deve fazer um novo generate.
Com isso terminamos a etapa inicial de configuração do projeto, podemos começar a programá-lo agora.
#3 – Padrão Repository
O próximo passo é criar o módulo que vai usar o Prisma para fazer as leituras e escritas no banco de dados. Para isso, é comum usarmos o padrão Repository que nada mais é do que um módulo que encapsula todas as funções de manipulação de uma tabela do banco de dados.
Crie um arquivo clientesRepository.ts na raiz do seu projeto e dentro dela inclua o seguinte código.
1 2 3 4 5 6 7 8 9 10 |
import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient(); async function connect() { await prisma.$connect(); } connect(); |
Esse código importa o Prisma Client e inicializa ele em uma variável local. Então eu defini uma função de conexão que abrir essa ponte de comunicação com o banco e já chamo a função imediatamente, garantindo que teremos uma conexão aberta e funcional quando precisarmos. Não se preocupe com a desconexão, ela é feita automaticamente quando o processo do Node se encerrar.
Agora precisamos criar as funções de manipulação do banco, uma a uma. Para isso, basta usarmos o objeto prisma, que já está conectado, e chamar as funções correspondentes ao que queremos fazer, iniciadas em find, create, update e delete, o que cobre todo o CRUD. Começando pelos finds:
1 2 3 4 5 6 7 8 9 10 11 |
export function getClientes() { return prisma.clientes.findMany(); } export function getCliente(id: number) { return prisma.clientes.findUnique({ where: { id } }) } |
Ambas são bem semelhantes, com a diferença que a segunda usa um filtro pois queremos apenas um cliente, aquele cujo id seja o passado por parâmetro. Repare que na primeira função usei findMany, pois eram vários clientes a serem encontrados, enquanto que na segunda usei findUnique, pois é apenas um e quero aproveitar o índice da chave primária (maior performance).
Agora vamos escrever as funções de escrita:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
export function addCliente(newCustomer: any) { return prisma.clientes.create({ data: newCustomer }); } export function updateCliente(id: number, newData: any) { return prisma.clientes.update({ where: { id }, data: newData }) } export async function deleteCliente(id: number) { return prisma.clientes.delete({ where: { id } }) } |
Na addCliente, usamos a função create que espera uma propriedade data com os dados a serem salvos no banco. Opcionalmente esta função espera uma propriedade select que pode mudar o retorno da mesma (por padrão ela retorna o último inserido).
Na updateCliente, usamos a função update, informando no where o filtro para selecionar os registros que serão atualizados, seguido da propriedade data informando os dados que serão atualizados.
E por fim, na deleteCliente usamos a função delete, que apenas espera um where com o filtro a ser usado para selecionar os registros a serem excluídos.
Com isso, você tem um exemplo de CRUD completo com Prisma ORM implementado no padrão repository. Se você tiver outras tabelas no seu banco, crie um módulo repository para cada uma.
#4 – Aplicação de Teste
O próximo passo é utilizar estes módulos que criamos de fato na nossa aplicação.
Como mencionei antes, o Prisma vai fazer a gestão não apenas das conexões com o banco, como a criação das tabelas necessárias, se elas ainda não existirem.
Então em nosso index.ts, basta importamos o repository e chamarmos as funções que quisermos testar. Exemplo de teste de escrita:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import { addCliente } from "./clientesRepository"; async function start() { const result = await addCliente({ nome: "Luiz", idade: 36, uf: "RS" }) console.log(result); } start(); |
O código não tem nada demais, eu carrego o repository da coleção que quero manipular e chamo a função apropriada, imprimindo no console o resultado ou o erro.
E com isso finalizamos este tutorial em que você aprendeu como fazer um CRUD bem simples usando TypeScript, Prisma e MongoDB.
Tenho certeza que juntando com outros conhecimentos de Node.js vai lhe permitir construir aplicações de verdade, como a webapi que ensino neste tutorial, com NestJS. Caso esteja trabalhando com monorepo, acho que esse outro tutorial vai te ajudar.
Um abraço e até a próxima!
Olá, tudo bem?
O que você achou deste conteúdo? Conte nos comentários.
MongoDb ou MySQL?
Esse tutorial é com banco SQL. Pode ser MySQL, MariaDB, Postgre e outros. Se procurar na barra de busca do blog por Prisma vai encontrar outros tutoriais e tem um que uso MongoDB.