Características • Instalação • Uso • API • Exemplos • Contribuir
API Backup Service é uma solução RESTful robusta e segura para realizar backups automatizados de coleções MongoDB. Este serviço atua como uma ponte de backup, permitindo que você preserve snapshots de seus dados de forma centralizada e organizada.
- ✅ Recebe dados de coleções MongoDB via API REST
- ✅ Armazena backups em banco de dados dedicado
- ✅ Mantém logs de backup em coleção separada (
backup_logs) - ✅ Substitui dados antigos automaticamente (drop e insert)
- ✅ Protege endpoints com autenticação Basic Auth
- ✅ Oferece endpoint de health check para monitoramento
- ✅ NOVO: Recupera dados de coleções específicas
- ✅ NOVO: Consulta logs de backup por database
- ✅ NOVO: Lista todos os databases do MongoDB
- Backup automatizado de dados críticos
- Sincronização de dados entre ambientes
- Histórico de snapshots para auditoria
- Disaster recovery e continuidade de negócio
| Recurso | Descrição |
|---|---|
| 🔐 Autenticação Segura | Basic Auth para proteger todos os endpoints |
| 📊 Sistema de Logs | Logs de backup armazenados em coleção separada |
| 🔄 Substituição Inteligente | Sobrescreve backups antigos automaticamente |
| 🏥 Health Check | Endpoint dedicado para monitoramento |
| 📝 TypeScript | Código totalmente tipado para maior segurança |
| ✅ Testado | Suíte completa de testes com Jest (49 testes) |
| 🔍 Recuperação de Dados | Recupere dados de qualquer coleção |
| 📋 Gestão de Logs | Consulte logs de backup por database |
| 🗄️ Listagem de Databases | Visualize todos os databases disponíveis |
| 📦 Grande Capacidade | Suporta payloads de até 1000mb (1GB) para backups volumosos |
| Tecnologia | Versão | Descrição |
|---|---|---|
| Node.js | 18+ | Runtime JavaScript |
| TypeScript | 5.9+ | Superset JavaScript tipado |
| Express | 5.1 | Framework web minimalista |
| MongoDB | 5.x | Banco de dados NoSQL |
| Mongoose | 5.13 | ODM para MongoDB |
| Jest | 30+ | Framework de testes |
Antes de começar, certifique-se de ter instalado:
1. Clone o repositório:
git clone https://github.com/GabrielFinotti/api-backup-service.git
cd api-backup-service2. Instale as dependências:
npm install3. Configure as variáveis de ambiente:
Crie um arquivo .env na raiz do projeto:
# Configurações do Servidor
PORT=3000
# Credenciais de Autenticação
SECRET_USER=seu_usuario
SECRET_PASS=sua_senha
# Conexão MongoDB
MONGO_URI=mongodb://localhost:27017
⚠️ Importante: Nunca commite o arquivo.envno repositório. Ele já está incluído no.gitignore.
# 1. Configure as variáveis de ambiente
cp .env.example .env
# Edite o arquivo .env com suas credenciais
# 2. Inicie o container
docker-compose up -d
# 3. Verifique o status
docker-compose ps
# 4. Ver logs
docker-compose logs -f
# 5. Parar o container
docker-compose down| Comando | Descrição |
|---|---|
npm run dev |
Inicia o servidor em modo de desenvolvimento com hot-reload |
npm run build |
Compila o projeto TypeScript para JavaScript |
npm start |
Inicia o servidor em modo produção |
npm test |
Executa a suíte de testes |
Inicie o servidor em modo de desenvolvimento:
npm run devO servidor estará disponível em http://localhost:3000
Para executar em produção:
# Compila o projeto
npm run build
# Inicia o servidor
npm startnpm testhttp://localhost:3000/api
Todos os endpoints (exceto /health) requerem autenticação Basic Auth.
- Combine suas credenciais no formato:
usuario:senha - Codifique em Base64
- Adicione no header:
Authorization: Basic <base64>
Exemplo de Codificação:
# Credenciais: admin:password123
# Base64: YWRtaW46cGFzc3dvcmQxMjM=
Authorization: Basic YWRtaW46cGFzc3dvcmQxMjM=Gerando Base64:
# Linux/Mac
echo -n "admin:password123" | base64
# Windows PowerShell
[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("admin:password123"))| Método | Endpoint | Descrição | Autenticação |
|---|---|---|---|
| GET | /api/health |
Health check da API | ❌ |
| POST | /api/backup |
Salvar backup de uma coleção | ✅ |
| POST | /api/recover |
Recuperar dados de uma coleção | ✅ |
| POST | /api/logs |
Listar logs de backup de um banco | ✅ |
| GET | /api/databases |
Listar todos os databases MongoDB | ✅ |
GET /api/health - Health Check
Verifica se a API está funcionando corretamente.
Autenticação: ❌ Não requerida
Resposta de Sucesso (200):
{
"status": "ok",
"timestamp": "2025-10-07T14:30:00.000Z"
}Exemplo cURL:
curl -X GET http://localhost:3000/api/healthExemplo JavaScript:
fetch('http://localhost:3000/api/health')
.then(response => response.json())
.then(data => console.log(data));POST /api/backup - Salvar Backup
Realiza o backup de uma coleção MongoDB.
Autenticação: ✅ Requerida (Basic Auth)
Headers:
Content-Type: application/json
Authorization: Basic <credenciais_base64>Body (JSON):
{
"database": "nome_do_banco",
"collectionsName": "nome_da_colecao",
"data": {
// Seus dados aqui (qualquer estrutura JSON válida)
}
}Parâmetros:
| Campo | Tipo | Descrição | Obrigatório |
|---|---|---|---|
database |
string |
Nome do banco de dados MongoDB de destino | ✅ |
collectionsName |
string |
Nome da coleção onde o backup será salvo | ✅ |
data |
any |
Dados a serem salvos no backup | ✅ |
Respostas:
✅ 200 OK - Backup salvo com sucesso
{
"status": "success",
"statusCode": 200,
"message": "Backup salvo com sucesso",
"data": {
"itemCount": 1,
"log": {
"database": "nome_do_banco",
"collectionsName": "nome_da_colecao",
"date": "07/10/2025",
"timestamp": "2025-10-07T14:30:00.000Z"
}
}
}❌ 400 Bad Request - Requisição inválida
{
"status": "error",
"statusCode": 400,
"message": "Requisição inválida",
"data": null
}🔒 401 Unauthorized - Não autorizado
{
"status": "error",
"statusCode": 401,
"message": "Não autorizado",
"data": null
}💥 500 Internal Server Error - Erro interno
{
"status": "error",
"statusCode": 500,
"message": "Ocorreu um erro interno no servidor",
"data": null
}POST /api/recover - Recuperar Dados
Recupera todos os dados de uma coleção específica.
Autenticação: ✅ Requerida (Basic Auth)
Headers:
Content-Type: application/json
Authorization: Basic <credenciais_base64>Body (JSON):
{
"database": "nome_do_banco",
"collectionName": "nome_da_colecao"
}Parâmetros:
| Campo | Tipo | Descrição | Obrigatório |
|---|---|---|---|
database |
string |
Nome do banco de dados MongoDB | ✅ |
collectionName |
string |
Nome da coleção a ser recuperada | ✅ |
Resposta de Sucesso (200):
{
"status": "success",
"statusCode": 200,
"message": "Dados recuperados com sucesso",
"data": {
"collectionName": "nome_da_colecao",
"database": "nome_do_banco",
"documentCount": 150,
"documents": [
{
"_id": "507f1f77bcf86cd799439011",
"campo1": "valor1",
"campo2": "valor2"
}
]
}
}Exemplo cURL:
curl -X POST http://localhost:3000/api/recover \
-H "Content-Type: application/json" \
-H "Authorization: Basic YWRtaW46cGFzc3dvcmQxMjM=" \
-d '{
"database": "meu_backup_db",
"collectionName": "usuarios_backup"
}'POST /api/logs - Listar Logs de Backup
Recupera todos os logs de backup de um banco de dados específico.
Autenticação: ✅ Requerida (Basic Auth)
Headers:
Content-Type: application/json
Authorization: Basic <credenciais_base64>Body (JSON):
{
"database": "nome_do_banco"
}Parâmetros:
| Campo | Tipo | Descrição | Obrigatório |
|---|---|---|---|
database |
string |
Nome do banco de dados MongoDB | ✅ |
Resposta de Sucesso (200):
{
"status": "success",
"statusCode": 200,
"message": "Logs recuperados com sucesso",
"data": {
"database": "meu_backup_db",
"logCount": 3,
"logs": [
{
"database": "meu_backup_db",
"collectionsName": "usuarios_backup",
"date": "07/10/2025",
"timestamp": "2025-10-07T14:30:00.000Z"
},
{
"database": "meu_backup_db",
"collectionsName": "produtos_backup",
"date": "07/10/2025",
"timestamp": "2025-10-07T13:15:00.000Z"
}
]
}
}Exemplo cURL:
curl -X POST http://localhost:3000/api/logs \
-H "Content-Type: application/json" \
-H "Authorization: Basic YWRtaW46cGFzc3dvcmQxMjM=" \
-d '{
"database": "meu_backup_db"
}'GET /api/databases - Listar Databases
Lista todos os databases disponíveis no MongoDB.
Autenticação: ✅ Requerida (Basic Auth)
Headers:
Authorization: Basic <credenciais_base64>Resposta de Sucesso (200):
{
"status": "success",
"statusCode": 200,
"message": "Databases recuperados com sucesso",
"data": {
"databaseCount": 3,
"databases": [
{
"name": "admin",
"sizeOnDisk": 40960,
"empty": false
},
{
"name": "meu_backup_db",
"sizeOnDisk": 8192000,
"empty": false
},
{
"name": "local",
"sizeOnDisk": 73728,
"empty": false
}
]
}
}Informações Retornadas:
| Campo | Tipo | Descrição |
|---|---|---|
name |
string |
Nome do database |
sizeOnDisk |
number |
Tamanho em bytes no disco |
empty |
boolean |
Se o database está vazio |
Exemplo cURL:
curl -X GET http://localhost:3000/api/databases \
-H "Authorization: Basic YWRtaW46cGFzc3dvcmQxMjM="Exemplo JavaScript:
const credentials = btoa('admin:password123');
fetch('http://localhost:3000/api/databases', {
method: 'GET',
headers: {
'Authorization': `Basic ${credentials}`
}
})
.then(response => response.json())
.then(data => console.log('Databases:', data))
.catch(error => console.error('Erro:', error));curl -X POST http://localhost:3000/api/backup \
-H "Content-Type: application/json" \
-H "Authorization: Basic YWRtaW46cGFzc3dvcmQxMjM=" \
-d '{
"database": "meu_backup_db",
"collectionsName": "usuarios_backup",
"data": {
"usuarios": [
{ "id": 1, "nome": "João Silva", "email": "joao@example.com" },
{ "id": 2, "nome": "Maria Santos", "email": "maria@example.com" }
],
"total": 2
}
}'const username = 'admin';
const password = 'password123';
const credentials = btoa(`${username}:${password}`);
const backupData = {
database: 'meu_backup_db',
collectionsName: 'usuarios_backup',
data: {
usuarios: [
{ id: 1, nome: 'João Silva', email: 'joao@example.com' },
{ id: 2, nome: 'Maria Santos', email: 'maria@example.com' }
],
total: 2
}
};
fetch('http://localhost:3000/api/backup', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Basic ${credentials}`
},
body: JSON.stringify(backupData)
})
.then(response => response.json())
.then(data => console.log('✅ Backup realizado:', data))
.catch(error => console.error('❌ Erro:', error));const axios = require('axios');
const username = 'admin';
const password = 'password123';
const credentials = Buffer.from(`${username}:${password}`).toString('base64');
const backupData = {
database: 'meu_backup_db',
collectionsName: 'usuarios_backup',
data: {
usuarios: [
{ id: 1, nome: 'João Silva', email: 'joao@example.com' },
{ id: 2, nome: 'Maria Santos', email: 'maria@example.com' }
],
total: 2
}
};
axios.post('http://localhost:3000/api/backup', backupData, {
headers: {
'Content-Type': 'application/json',
'Authorization': `Basic ${credentials}`
}
})
.then(response => console.log('✅ Backup realizado:', response.data))
.catch(error => console.error('❌ Erro:', error.response?.data || error.message));import requests
from base64 import b64encode
# Configuração
username = 'admin'
password = 'password123'
credentials = b64encode(f'{username}:{password}'.encode()).decode()
url = 'http://localhost:3000/api/backup'
headers = {
'Content-Type': 'application/json',
'Authorization': f'Basic {credentials}'
}
data = {
'database': 'meu_backup_db',
'collectionsName': 'usuarios_backup',
'data': {
'usuarios': [
{'id': 1, 'nome': 'João Silva', 'email': 'joao@example.com'},
{'id': 2, 'nome': 'Maria Santos', 'email': 'maria@example.com'}
],
'total': 2
}
}
# Realizar backup
response = requests.post(url, headers=headers, json=data)
if response.status_code == 200:
print('✅ Backup realizado:', response.json())
else:
print('❌ Erro:', response.json())# Configuração
$username = "admin"
$password = "password123"
$credentials = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("${username}:${password}"))
$headers = @{
"Content-Type" = "application/json"
"Authorization" = "Basic $credentials"
}
$body = @{
database = "meu_backup_db"
collectionsName = "usuarios_backup"
data = @{
usuarios = @(
@{ id = 1; nome = "João Silva"; email = "joao@example.com" }
@{ id = 2; nome = "Maria Santos"; email = "maria@example.com" }
)
total = 2
}
} | ConvertTo-Json -Depth 10
# Realizar backup
Invoke-RestMethod -Uri "http://localhost:3000/api/backup" -Method Post -Headers $headers -Body $body| Aspecto | Implementação |
|---|---|
| Autenticação | Basic Auth em todos os endpoints protegidos |
| Variáveis de Ambiente | Credenciais armazenadas em .env (não versionado) |
| Validação | Middleware valida credenciais antes de processar requisições |
| Headers | Verificação de headers de autenticação obrigatórios |
- ✅ Use HTTPS: Sempre use HTTPS em produção para criptografar credenciais na transmissão
- ✅ Credenciais Fortes: Use senhas complexas e únicas
- ✅ Rotação de Credenciais: Altere senhas periodicamente
- ✅ Rate Limiting: Considere implementar rate limiting para prevenir ataques de força bruta
- ✅ Logs de Auditoria: Monitore logs para detectar tentativas de acesso não autorizado
- ✅ Firewall: Configure firewall para permitir apenas IPs confiáveis
graph LR
A[Cliente] -->|POST /api/backup| B[API]
B -->|Autentica| C{Válido?}
C -->|Não| D[401 Unauthorized]
C -->|Sim| E[Conecta MongoDB]
E --> F[Drop Coleção de Dados]
F --> G[Insere Dados]
G --> H[Atualiza backup_logs]
H --> I[200 Success]
| Característica | Descrição |
|---|---|
| Substituição Automática | A coleção de dados é dropada antes de inserir novos dados (sobrescreve backup anterior) |
| Separação de Dados e Logs | Dados são salvos na coleção especificada, logs em backup_logs |
| Logs Persistentes | A coleção backup_logs é atualizada (upsert) a cada backup bem-sucedido |
| Metadados de Log | Armazena database, collectionsName, date e timestamp na coleção de logs |
| Contagem de Itens | Retorna a quantidade de itens salvos ao invés dos dados completos |
| Sanitização de Dados | Remove automaticamente chaves que começam com $ (reservadas pelo MongoDB) |
| Inserção Otimizada | Usa insertMany para arrays e insertOne para objetos únicos |
| Formato da Data | DD/MM/YYYY (formato brasileiro) |
| Dados Puros | Apenas os dados (arrays/objetos) são salvos na coleção principal |
| Limite de Payload | Suporta requisições de até 1000mb (1GB) para grandes volumes de dados |
Entrada:
{
"database": "backup_db",
"collectionsName": "users",
"data": {
"users": [{"id": 1, "name": "João"}]
}
}Armazenado na Coleção users (dados apenas):
{
"users": [{"id": 1, "name": "João"}]
}Armazenado na Coleção backup_logs (metadados):
{
"database": "backup_db",
"collectionsName": "users",
"date": "07/10/2025",
"timestamp": "2025-10-07T14:30:00.000Z"
}Retorno da API:
{
"status": "success",
"statusCode": 200,
"message": "Backup salvo com sucesso",
"data": {
"itemCount": 1,
"log": {
"database": "backup_db",
"collectionsName": "users",
"date": "07/10/2025",
"timestamp": "2025-10-07T14:30:00.000Z"
}
}
}💡 Nota: A API retorna
itemCountcom a quantidade de documentos inseridos, não os dados completos. Para arrays, retorna o tamanho do array; para objetos, retorna 1.
O projeto inclui testes unitários para componentes críticos:
| Componente | Arquivo | Descrição |
|---|---|---|
| Auth Middleware | auth.middleware.test.ts |
Testa autenticação Basic Auth |
| Backup Service | backup.service.test.ts |
Testa lógica de backup |
# Executar todos os testes
npm test
# Executar em modo watch
npm test -- --watch
# Executar com cobertura
npm test -- --coveragetest/
├── middlewares/
│ └── auth.middleware.test.ts # Testes de autenticação
└── services/
└── backup.service.test.ts # Testes do serviço de backup
api-backup-service/
├── src/ # Código fonte
│ ├── controllers/ # Controladores da API
│ │ └── saveBackup.controller.ts
│ ├── database/ # Configuração do banco de dados
│ │ └── config/
│ │ └── createConnection.ts
│ ├── interface/ # DTOs e interfaces TypeScript
│ │ └── backupDataInput.dto.ts
│ ├── middlewares/ # Middlewares Express
│ │ └── auth.middleware.ts
│ ├── routes/ # Definição de rotas
│ │ └── backup.route.ts
│ ├── services/ # Lógica de negócio
│ │ └── backup.service.ts
│ └── server.ts # Ponto de entrada da aplicação
│
├── test/ # Testes unitários
│ ├── middlewares/
│ │ └── auth.middleware.test.ts
│ └── services/
│ └── backup.service.test.ts
│
├── .env # Variáveis de ambiente (não versionado)
├── .gitignore # Arquivos ignorados pelo Git
├── jest.config.mjs # Configuração do Jest
├── LICENSE # Licença MIT
├── package.json # Dependências e scripts
├── README.md # Este arquivo
├── tsconfig.json # Configuração TypeScript
└── tsconfig.test.json # Configuração TypeScript para testes
Certifique-se de configurar as seguintes variáveis no ambiente de produção:
PORT=3000
SECRET_USER=seu_usuario_seguro
SECRET_PASS=sua_senha_complexa
MONGO_URI=mongodb://seu-servidor:27017- ✅ Use HTTPS: Sempre configure SSL/TLS
- ✅ Credenciais Fortes: Use senhas complexas e únicas
- ✅ Firewall: Configure regras de firewall adequadas
- ✅ Monitoramento: Implemente logs e alertas
- ✅ Backup: Configure backup regular do MongoDB
Contribuições são muito bem-vindas! Este projeto segue o padrão de Conventional Commits.
- Fork o projeto
- Clone seu fork:
git clone https://github.com/seu-usuario/api-backup-service.git - Crie uma branch para sua feature:
git checkout -b feature/minha-feature - Commit suas mudanças:
git commit -m 'feat: adiciona nova feature' - Push para a branch:
git push origin feature/minha-feature - Abra um Pull Request
feat:Nova funcionalidadefix:Correção de bugdocs:Alterações na documentaçãostyle:Formatação, ponto e vírgula, etcrefactor:Refatoração de códigotest:Adição ou correção de testeschore:Atualizações de build, configs, etc
- Mantenha o código limpo e bem documentado
- Adicione testes para novas funcionalidades
- Siga o estilo de código existente
- Atualize a documentação quando necessário
Para ver o histórico completo de mudanças, consulte o arquivo CHANGELOG.md.
- ✨ Novo: Limite de payload aumentado para 1000mb (1GB)
- � Melhorado: Suporte para backups de grandes volumes de dados
- 🎯 Impacto: Permite backup de coleções com milhares de documentos em uma única requisição
Nenhum problema conhecido no momento. Se encontrar algum bug, por favor abra uma issue.
Se você tiver dúvidas ou precisar de ajuda:
- 📧 Abra uma issue
- 💡 Consulte a documentação
- 🌟 Dê uma estrela no projeto se ele foi útil!
Este projeto está licenciado sob a Licença MIT - veja o arquivo LICENSE para mais detalhes.
TL;DR: Você pode usar, copiar, modificar, distribuir e até vender este software, desde que mantenha o aviso de copyright original.
Gabriel H. Finotti
- GitHub: @GabrielFinotti
- Projeto: api-backup-service