Criando uma WebAPI com Node.js e PostgreSQL

Node.js

Criando uma WebAPI com Node.js e PostgreSQL

Luiz Duarte
Escrito por Luiz Duarte em 22/06/2023
Junte-se a mais de 34 mil devs

Entre para minha lista e receba conteúdos exclusivos e com prioridade

Hoje vou ensinar como que você pode usar Node.js com PostgreSQL para criar uma WebAPI. Apesar de MongoDB e demais bases não relacionais serem a escolha mais comum com Node, muitos programadores, geralmente com outros backgrounds em programação, conhecem e usam PostgreSQL e não querer abrir mão de seu conhecimento a respeito. Sendo assim, acredito que este post ajudará quem estiver migrando de plataforma, mas não quer migrar de banco.

Existem diversas maneiras de usar PostgreSQL com Node. Uma vez que é um banco de dados muito popular, logo, é possível que você encontre muita informação diferente na Internet à respeito. Entenda que te mostrarei UMA das INÚMERAS opções de como conectar no PostgreSQL com Node.js.

Veremos neste artigo:

  1. Criando o banco de dados
  2. Criando a API
  3. Criando a listagem de clientes
  4. Criando a pesquisa de um cliente
  5. Excluindo um cliente
  6. Adicionando um cliente
  7. Atualizando um cliente
  8. Bônus

Opcionalmente, você pode assistir ao vídeo abaixo, é o mesmo conteúdo.

Então vamos lá!

Parte 1: Criando o banco de dados

Se você nunca programou com Node e Postgre antes, vou deixar abaixo um vídeo ensinando a instalação do ambiente.

Quando estiver com o ambiente pronto, pode criar o banco e tabela para nossa aplicação. Abaixo, o SQL de criação da tabela que vamos usar, você pode executar ele na funcionalidade browse que tem no painel administrativo do ElephantSQL ou criar pelo PgAdmin:

Não esqueça também de adicionar algumas linhas nesta tabela pelo PgAdmin ou painel web do ElephantSQL.

Pronto, banco criado e pronto para usarmos!

Parte 2: Criando a API

Agora que já temos nosso banco de dados PostgreSQL pronto, com dados de exemplo e aprendemos como fazer a conexão nele, vamos criar uma API básica usando Express para conseguir criar um CRUD com Node.js + PostgreSQL no próximo passo.

Vamos começar adicionando a dependência do Express (framework web) no projeto via linha de comando na pasta do mesmo e também a dependência do pacote pg, que é o driver nativo do PostgreSQL e dotenv, para variáveis de ambiente:

Na sequência crie um arquivo .env na raiz da sua aplicação para adicionarmos as variáveis de ambiente que vamos precisar, como segue. Ajuste a sua connection string de acordo com seu ambiente.

A seguir, vamos criar um arquivo index.js na pasta do projeto onde vamos criar o nosso servidor da API para tratar as requisições que chegarão em breve. Vamos começar bem simples, apenas definindo as constantes locais que serão usadas mais pra frente e carregando as variáveis de ambiente:

Agora, logo abaixo, vamos configurar nossa aplicação (app) Express para usar o body parser do Express, permitindo que recebamos mais tarde POSTs no formato JSON:

Na sequência, vamos criar um middleware inicial que apenas exibe uma mensagem de sucesso quando o usuário requisitar um GET na raiz da API (/) para ver se está funcionando.

Note que eu digo que requisições que chegarem na raiz devem ser mandadas para a função que imprime uma mensagem. Por fim, adicionamos as linhas abaixo no final do arquivo que dão o start no servidor da API:

Teste sua API executando via console o seu index.js com o comando ‘node index.js’. Você deve ver a mensagem de ‘API funcionando!’ no console, e se acessar no navegador localhost:3000 deve ver o JSON default que deixamos na rota raiz!

API Funcionando

Parte 3: Criando a listagem de clientes

Agora vamos abrir o nosso db.js e criar a conexão com nosso banco de dados, usando o pacote que acabamos de instalar. Antes de tudo, esta será uma função assíncrona que utilizará async/await, logo, declaro ela usando async.

Segundo, não podemos sair criando conexões infinitas no banco pois isso além de ser lento é inviável do ponto de vista de infraestrutura. Usaremos aqui um conceito chamado connection pool, onde um objeto irá gerenciar as nossas conexões, para abrir, fechar e reutilizar conforme possível. Vamos guardar este único pool em uma variável global, que testamos logo no início da execução para garantir que se já tivermos um pool, que vamos utilizar o mesmo.

Passando essa verificação inicial, nós começamos o código da função carregando o nosso pacote pg, mais especificamente uma classe Pool dentro dele que fará o gerenciamento de conexões pra gente. Com esta classe Pool, consigo instanciar um novo pool de conexões passando a connection string fornecida pelo meu provedor.

O código a seguir, marcado com um comentário, é apenas para testarmos se nossa conexão foi realizada com sucesso: abrimos uma conexão com o pool e usamos ela para fazer uma consulta pela hora atual do servidor, imprimindo no console o resultado.

Note que tive de usar o await no client.query, pois ele é assíncrono. Note também que depois de usar, liberamos a conexão de novo usando client.release. No fim da function de conexão, eu armazeno ela em uma variável global.

Importante você garantir que tanto no if inicial quanto no return, que estejamos chamando a função connect do pool para que essa conexão resultante seja usado por quem chamar esta função de conexão que criamos.

Para testar essa função de conexão, volte no index.js e apenas carregue o pacote db.js como abaixo e mande rodar a API de novo.

Agora vamos voltar ao db.js e vamos criar a função que vai retornar os clientes, como abaixo.

E com ela podemos voltar ao index.js e criar uma rota /clientes que listará todos os clientes do banco de dados, como abaixo, logo abaixo da rota / (raiz):

Agora, ao executarmos novamente nosso projeto e ao acessarmos a URL localhost:3000/clientes, veremos todos os clientes cadastrados no banco de dados (no passo 2, lembra?). Os campos que irão aparecer serão conforme a sua tabela:

Todos clientes

E com isso finalizamos a listagem de todos clientes na nossa API!

Parte 4: Criando a pesquisa de um cliente

Agora, se o usuário quiser ver apenas um cliente, ele deverá passar o ID do mesmo na URL, logo após o /clientes. Para permitir isso, vamos começar criando uma nova função no db.js chamada selectCustomer (no singular) e exportando-a ao final do módulo.

Repare que aqui usei $1 no campo ID da consulta e que passei um segundo parâmetro como um array de valores, informando apenas o id. Esse formato costumamos chamar de prepared statement (ou prepared query) e é uma forma de nos defendermos de um ataque comum chamado SQL Injection. Assim, o parâmetro id será validado pelo driver e inserido no lugar do placeholder $1.

Agora vamos criar uma nova rota, /clientes/:id, para aceitar um parâmetro ID. Certifique-se de colocar esta nova rota antes da anterior, caso contrário o Express sempre processará com o outro código, mesmo que venha o ID na URL:

Mande rodar e teste no navegador, verá que está funcionando perfeitamente (os campos que vão aparecer são conforme sua tabela)!

Apenas um

E com isso terminamos a pesquisa por cliente.

Parte 5: Excluindo um cliente

Para excluir um cliente vamos fazer um processo parecido com o de pesquisar um cliente, no entanto, mudaremos o verbo HTTP de GET para DELETE, como manda o protocolo HTTP. Volte ao db.js e adicione uma nova função, a deleteCustomer:

Agora adicione a nova rota logo após as demais no index.js:

Note que desta vez o parâmetro id na URL é usado como filtro para a exclusão e dentro do processamento da requisição delete do router eu mando um SQL de DELETE passando o ID numérico, retornando um código HTTP 204 que significa “sucesso sem retorno”. Para testar essa rota você tem duas alternativas, ou usa o POSTMAN para forjar um DELETE, como abaixo:

DELETE com POSTMAN

Ou fazer via console usando cURL (se tiver ele instalado na sua máquina):

Em ambos os casos você deve obter uma resposta 200 OK (caso não tenha dado erro) e se mandar listar todos clientes novamente, verá que o número 1 sumiu.

Curso Node.js e MongoDB

Parte 6: Adicionando um cliente

Agora vamos adicionar um novo cliente com um POST na rota /clientes. Mas antes disso, crie a função insertCustomer no db.js:

Note que aqui como temos diversos campos que precisam ser passados, optei por receber um objeto por parâmetro e desmembrei o mesmo usando suas propriedades e os placeholders $1, $2, etc.

Adicione esta nova rota logo abaixo das anteriores no index.js:

Nela, eu pego o objeto JSON deve vir junto ao POST e passo como parâmetro da função insertCustomer, gerando um comando de INSERT que vai ser executado no banco de dados e retorno um 201 que significa “cadastrado com sucesso” no protocolo HTTP. Para testar esse POST, você usar o POSTMAN, como mostrado anteriormente (mude os campos conforme a sua tabela):

POST no Postman

Se quiser fazer via cURL:

Se testar agora vai ver que é possível inserir novos registros no banco de dados através de requisições POST. Repare que não estou fazendo nenhuma validação aqui, que é assunto deste outro tutorial.

Livro Node.js

Parte 7: Atualizando um cliente

E para finalizar o CRUD, vamos ver como podemos atualizar um cliente no banco de dados PostgreSQL através da nossa API Node.js. Para fazer updates podemos usar os verbos PUT ou PATCH. O protocolo diz que devemos usar PUT se pretendemos passar todos os parâmetros da entidade que está sendo atualizada ou ainda quando quisermos adicionar elementos em uma coleção, então usaremos PATCH nesta API que é o verbo para atualizações parciais.

Mas antes disso, db.js, função updateCustomer:

Crie uma rota PATCH em /clientes esperando o ID do cliente a ser alterado.

No código acima, pegamos o ID que veio na URL e as demais informações que vieram no corpo da requisição, depois monto o UPDATE com os parâmetros recebidos (no db.js) e mando para nossa função de executar SQL (client.query).

Para testar uma requisição PATCH, você pode usar o POSTMAN (mude os campos de acordo com sua tabela):

PATCH no POSTMAN

Ou o cURL:

O resultado é o mesmo: o cliente cujo ID=4 vai ter o seu nome alterado para ‘fernando’. Note que se ele não existir, ocasionará um erro que será apresentado no corpo da resposta.

E com isso finalizamos o CRUD da nossa API Node.js que usa PostgreSQL como persistência de dados.

Curso FullStack

Bônus 1: ORM

Se você não curte muito a ideia de ficar usando SQL no meio dos seus códigos JS, experimente usar alguma biblioteca ORM (Object-Relational Mapping) como o Sequelize.

Bônus 2: Segurança

Segurança é um fator muito importante em Web APIs corporativas e aqui não é exceção. Sugiro que dê uma olhada neste artigo sobre JSON Web Token, que vai lhe ajudar com este tópico.

Também vale a pena estar em um servidor bem configurado, neste tutorial aqui ensino como fazer isso na Amazon AWS.

Até a próxima!

Olá, tudo bem?

O que você achou deste conteúdo? Conte nos comentários.

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *