Guia para Iniciantes: Criando uma API com Node.js, PostgreSQL e Padrão MVC
Tags: braziliandevs
Published: 2023-08-22 23:05:11

*Introdução*

Este artigo de hoje, está mais para uma guia de introdução para a construção de uma API utilizando as tecnologias mencionadas no título: `Node.JS`, `PostgreSQL` e utilizando o `padrão MVC`.

Não tive a pretensão de escrever um guia completo, procurei escrever de uma maneira que eu gostaria de ter encontrado quando comecei a estudar, sem ter todas as respostas, mas que me indicassem um norte de onde seria o próximo passo para estudar e aprofundar.

Este guia busca isso, ser menos teórico, quando comparado a publicações anteriores, e mais aplicação prática. Assim como, estou aceitando correções, pois também estou aprendendo e compartilhando como eu mesmo faço.

> Este artigo é parte de uma síntese de anotações soltas sobre desenvolvimento web e do Bootcamp que estou fazendo atualmente em desenvolvimento full stack.

Então, vamos começar!
## Passo 1: Configuração do Projeto

Primeiro, é necessário configurar o ambiente de desenvolvimento e nos certificamos de que possuímos o `Node.Js` instalado em nosso sistema operacional. Para isto, verifique se o `Node.Js` com o seguinte comando em seu terminal:

```bash
node -v
```

Se o `Node.Js` estiver instalado, aparecerá a versão correspondente. Se não, não tem problema. Basta instalar o `Node.Js` seguindo as instruções no [site oficial](https://nodejs.org/en)

Em seguida, crie uma pasta onde será armazenado o seu projeto. No meu caso, nomearei a pasta de `projdesafio` pois estou dando prosseguimento ao projeto relacionado a um desafio feito no [Bootcamp da Atlantico Avanti](https://www.atlanticoavanti.com.br/bootcamp)

- Em seu terminal, digite o seguinte comando para a criação de uma pasta:
```bash
# mkdir nome_da_pasta
mkdir projdesafio
```

- Navegue até a pasta criada usando o seguinte comando:
```bash
# cd nome_da_pasta
cd projdesafio
```

- Agora, dentro da pasta, é hora de **iniciar o projeto em Node.Js**, com o seguinte comando:
```bash
npm init -y
```

Ao executar este último comando, será criado um arquivo `package.json` com valores padrões. Este arquivo é essencial para projetos em `Node.Js`, pois contém informações sobre os projetos, dependências, scripts personalizados (olá [nodemon](https://nodemon.io/)!) e outros.

> O gerenciador de pacotes fornecerá um método para instalar novas dependências (também chamadas de "pacotes"), gerenciar onde os pacotes são armazenados em seu sistema de arquivos e oferecer recursos para que você possa publicar seus próprios pacotes.
> 
> Em teoria, você pode não precisar de um gerenciador de pacotes e poderia baixar e armazenar manualmente as dependências do seu projeto, mas um gerenciador de pacotes lidará automaticamente com a instalação e desinstalação dos pacotes. Se você não usasse um, teria que lidar manualmente com isso.
> [mdn web docs](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Package_management)

- No diretório `projdesafio`, crie um arquivo chamado `app.js`. E assim, estará nossa estrutura de arquivos até aqui:
```bash
projdesafio/
├── app.js
└── package.json
```

- Agora vamos instalar o `Express` como uma dependência do nosso projeto. Abra o seu terminal e introduza este comando para a instalação:
```bash
npm install express
```

Após a instalação, aparecerá uma nova chamada `node_modules` dentro da sua pasta. Em breve, vamos começar a a configurar o nosso arquivo `app.js` para utilizar o Express e começar a construir a nossa API.

```bash
projdesafio/
├── node_modules/
│   ├── ... (dependências instaladas)
├── app.js
└── package.json
```
## Passo 2: Configurando o Banco de Dados

Perfeito!

Vamos continuar agora para a parte do banco de dados. No projeto do [Bootcamp](https://www.atlanticoavanti.com.br/bootcamp) eu estarei partindo do principio que você conhece tanto as partes DDL quanto DML em SQL.

Caso não tenha ideia do que estou falando, segue esta publicação onde abordei estes assuntos:

- [Entendendo a Relação entre SQL, DML e DDL: Fundamentos de Banco de Dados](https://dev.to/matt1cs/entendendo-a-relacao-entre-sql-dml-e-ddl-fundamentos-de-banco-de-dados-23bi)

O Banco de Dados já está criado com esta tabela a seguir:

```sql
-- tabela cliente
create table Cliente (
	id serial primary key,
	nome varchar(255) not null,
	cpf varchar(11) not null unique
);

-- tabela certidao
create table Certidao (
	id serial primary key,
	cliente_id int not null references Cliente(id),
	data_emissao date not null,
	hora_emissao time not null,
	validade date not null,
	codigo_validacao boolean not null
);
```

Esta é só uma parte, como esta publicação só tem o intuito de apresentar **inicialmente** e não se aprofundará sobre outros aspectos.

- No diretório `projdesafio`, abra o terminal e instale o pacote `pg`, que vai nos permitir termos uma interface com o banco de dados `PostgreSQL` em nossa aplicação `Node.Js`.
```bash
npm install pg
```

- Em seguida, crie uma pasta chamada `config`, é esta pasta que será usada para armazenar as configurações com o nosso banco de dados.
```bash
projdesafio/
├── node_modules/
│   ├── ... (dependências instaladas)
├── config/
├── app.js
└── package.json
```

- Dentro da pasta `config`, crie um arquivo chamado `db.js`. Este arquivo conterá o código para estabelecer conexão com o `PostgreSQL`.
```js
const { Pool } = require('pg');

// Configurações do banco de dados
const pool = new Pool({
  user: 'altere_para_seu_usuario',
  host: 'localhost',
  database: 'altere_para_o_seu_banco_de_dados',
  password: 'altere_para_a_sua_senha',
  port: 5432, // Porta padrão do PostgreSQL
});

module.exports = pool; //Exportando para usarmos posteriomente

```

Usamos o `module.exports` para permitir que outras partes da aplicação posteriormente possam utilizar estas configurações para acessar o banco de dados.

Desta forma, posteriormente, outros módulos poderão obter uma conexão com o banco de dados, e assim realizar as operações `SQL` necessárias da nossa API.

- Assim agora se encontrar a nossa estrutura de pastas e arquivos:
```bash
projdesafio/
├── node_modules/
│   ├── ... (dependências instaladas)
├── config/
│   ├── db.js
├── app.js
└── package.json
```

## Passo 3: Estrutura MVC

> Apesar de muitas pessoas considerarem essa sigla como um padrão de design de interface, na verdade ele **é um padrão de arquitetura de software responsável por contribuir na otimização da velocidade entre as requisições feitas pelo comando dos usuários**.   
>  
> Com quase 50 anos de formulação, a arquitetura MVC é dividida em três componentes essenciais: Model, Controller e View.
> [Le wagon - O que é MVC?](https://blog.lewagon.com/pt-br/skills/o-que-e-padrao-mvc/)


Como neste projeto aqui se trata apenas de uma API sem interface gráfica, a pasta `views` ficará vazia, mas será criadas apenas para fins de documentação desta publicação.

- No diretório `projdesafio`, crie três pastas: `models`, `controllers`, `views`. 
```bash
mkdir models controllers views
```

- Estrutura de pastas e arquivos do projeto até então:
```bash
projdesafio/
├── node_modules/
│   ├── ... (dependências instaladas)
├── config/
│   ├── db.js
├── models/
├── controllers/
├── views/
├── app.js
└── package.json
```

## Passo 4: Modelagem de Dados

Vamos começar pela criação do modelo na pasta `models`, seguindo o padrão MVC. Criaremos duas funções realizando **funções SQL** para interagir com o banco de dados.

- getAllClients (buscar todos os clientes)
- createNewClient(adicionar novo cliente)

No diretório `projdesafio/models`, crie um arquivo chamado `ClienteModel.js`. Abra o arquivo `ClienteModel.js` e importe a configuração com o banco de dados e implemente as funções e consultas.

```js
const db = require('../config/db'); // Importe a configuração do banco de dados

const Cliente = {
  getAllClients: async () => {
    try {
      const query = 'SELECT * FROM Cliente';
      const result = await db.query(query);
      return result.rows;
    } catch (error) {
      throw error;
    }
  },

  createNewClient: async (nome, cpf) => {
    try {
      const query = 'INSERT INTO Cliente (nome, cpf) VALUES ($1, $2) RETURNING *';
      const values = [nome, cpf];
      const result = await db.query(query, values);
      return result.rows[0];
    } catch (error) {
      throw error;
    }
  }
};

module.exports = Cliente;
```

Exportando o módulo como  `Cliente`, agora podemos acessar quando criarmos os nossos controladores para acessar o banco de dados, realizar as `funções SQL` e implementar as operações da nossa API.

- Aqui está a estrutura até então do nosso projeto:
```bash
projdesafio/
├── node_modules/
│   ├── ... (dependências instaladas)
├── config/
│   ├── db.js
├── models/
│   ├── ClienteModel.js
├── controllers/
├── views/
├── app.js
└── package.json
```

> Isso tudo aqui é muito básico e eu ainda estou aprendendo também. Pode expandir, adicionar validações, tratamento de erros e outras funcionalidades.

## Passo 5: Criando Controladores

Seguindo vamos para a criação dos controladores que irão manipular as ações relacionadas ao modelo `Cliente`.

`Controladores` fazem a intermediação entre as requisições HTTP e os Models.

- No diretório `projdesafio/controllers`, crie um arquivo chamado `clienteController.js`. Abra o arquivo `clienteController.js` e importe o modelo criado anteriormente:
```js
const ClienteModel = require('../models/ClienteModel'); // Importe o modelo

const clienteController = {
  getAllClients: async (req, res) => {
    try {
      const clients = await ClienteModel.getAllClients();
      res.status(200).json(clients);
    } catch (error) {
      res.status(500).json({ error: 'Erro ao obter lista de clientes.' });
    }
  },

  createNewClient: async (req, res) => {
    const { nome, cpf } = req.body;
    try {
      const newClient = await ClienteModel.createNewClient(nome, cpf);
      res.status(201).json(newClient);
    } catch (error) {
      res.status(500).json({ error: 'Erro ao criar novo cliente.' });
    }
  }
};

module.exports = clienteController;

```

A partir daqui, podemos configurar o nosso `app.js` usando os controladores para definir as rotas e quais ações correspondentes.

- Aqui está a estrutura até então do nosso projeto:
```bash
projdesafio/
├── node_modules/
│   ├── ... (dependências instaladas)
├── config/
│   ├── db.js
├── models/
│   ├── ClienteModel.js
├── controllers/
│   ├── clienteController.js
├── views/
├── app.js
└── package.json
```
## Passo 6: Integração de Controladores e Modelos

Abra o nosso arquivo `app.js` e vamos começar importando as dependências necessárias, incluindo a configuração com o banco de dados, o `express` e o controlador.

```js
const express = require('express');
const db = require('./config/db');
const clienteController = require('./controllers/clienteController');

const app = express(); //Instância do Express
const PORT = 3000; //Porta para o servidor, por exemplo a 3000

app.use(express.json()); //Middleware para tratar os dados no formato JSON

app.get('/api/clientes', clienteController.getAllClients); //Rota para obter todos os clientes
app.post('/api/clientes', clienteController.createNewClient); //Rota para adicionar um novo cliente

app.listen(PORT, () => {
  console.log(`Servidor na porta ${PORT}`);
}); 
```

## Passo 7: Testando a API

Vamos testar a nossa API utilizando o `Postman`

- Testando a rota `GET` para listar todos os clientes:
```bash
1- Servidor precisa estar em execução, assim como o banco de dados;
2- Crie uma nova requisição no Postman;
3- Selecione o método HTTP como GET;
4- Insira a URL: http://localhost:3000/api/clientes
5- Clique em Send (Enviar)
```

- Testando a rota `POST` para criar um novo cliente:
```bash
1- Crie uma nova requisição no Postman;
2- Selecione o método HTTP como POST;
4- Insira a URL: http://localhost:3000/api/clientes
5- Na seção Body, selecione raw e escolha o formato JSON.
6- Insira os dados no formato JSON:
{
  "nome": "Blue",
  "cpf": "12345678901"
}
7- Clique em Send (Enviar)
```

O `Postman` enviará as requisições para o nosso servidor local e você verá as respostas da API.

## Conclusão

Parabéns! Terminamos nosso guia de introdução aqui, e fica para você continuar estudando, implementando e melhorando a aplicação.

A partir daí, você consegue estabelecer um CRUD (criar, ler, atualizar e deletar), seguindo o mesmo fluxo de informação de um módulo para outro, utilizando `Node.Js`, `PostgreSQL` e o padrão de `arquitetura MVC`.