API REST desenvolvida com FastAPI para gerenciamento de usuários e empresas, aplicando boas práticas de desenvolvimento backend, arquitetura em camadas e documentação automática de APIs.
O projeto foi desenvolvido utilizando uma arquitetura organizada em Routes → Services → Repositories → Models, com autenticação JWT, banco de dados relacional, migrações versionadas e conteinerização com Docker.
- Python 3.12
- FastAPI
- SQLAlchemy
- Pydantic
- Uvicorn
- PostgreSQL
- Alembic (Migrations)
- JWT Authentication com expiração obrigatória
- Hash de senhas com Argon2id e migração automática de bcrypt
- Docker
- Docker Compose
- GitHub Actions (CI)
- Pytest
- Cadastro de usuários com validação de credenciais
- Login com JWT
- Proteção de rotas autenticadas
- Cadastro de empresas
- Validação de CNPJ numérico e alfanumérico
- Listagem paginada
- Consulta por CNPJ
- Atualização de empresas
- Soft Delete
- Auditoria de registros
- Paginação
- Filtros
- Ordenação
- Tratamento global de exceções
- Respostas padronizadas
- Documentação automática com Swagger/OpenAPI
Cliente
│
▼
FastAPI
│
▼
Routes
│
▼
Services
│
▼
Repositories
│
▼
PostgreSQL
api_cnpj/
│
├── core/
│ ├── cnpj.py
│ ├── config.py
│ ├── exceptions.py
│ ├── logger.py
│ ├── middleware.py
│ ├── responses.py
│ └── security.py
│
├── database/
│
├── migrations/
│
├── models/
│
├── repositories/
│
├── routes/
│
├── schemas/
│
├── services/
│
├── tests/
│
├── Dockerfile
├── docker-compose.yml
├── main.py
└── README.md
| Método | Endpoint | Descrição |
|---|---|---|
| POST | /auth/register | Cadastro de usuário |
| POST | /auth/login | Login e geração do JWT |
| Método | Endpoint | Descrição |
|---|---|---|
| GET | /health/live | Confirma que o processo está ativo |
| GET | /health/ready | Confirma o acesso da aplicação ao banco |
Todas as respostas incluem o cabeçalho X-Request-ID. Um identificador válido
enviado pelo cliente é preservado; caso contrário, a API gera um UUID. Os logs
são enviados para a saída padrão com método, caminho, status e duração.
| Método | Endpoint | Descrição |
|---|---|---|
| GET | /empresas/ | Lista empresas |
| POST | /empresas/ | Cadastra empresa |
| PUT | /empresas/{cnpj} | Atualiza empresa |
| DELETE | /empresas/{cnpj} | Remove empresa (Soft Delete) |
A API aceita o formato numérico tradicional e o novo formato alfanumérico, mantendo os dois últimos caracteres como dígitos verificadores. Pontos, barra e hífen são removidos, e letras são normalizadas para maiúsculas antes da validação pelo módulo 11.
Exemplos válidos: 12.345.678/0001-95 e 12.ABC.345/01DE-35. Nas rotas que
recebem {cnpj}, use o valor sem pontuação, como 12ABC34501DE35.
O endpoint GET /empresas/ aceita os seguintes parâmetros de consulta:
| Parâmetro | Padrão | Descrição |
|---|---|---|
| page | 1 | Página da listagem (mínimo: 1) |
| limit | 10 | Registros por página (entre 1 e 100) |
| cidade | — | Filtra por cidade (até 100 caracteres) |
| estado | — | Filtra por UF (duas letras) |
| ordem | id | id, nome, cnpj, cidade ou estado |
| direcao | asc | asc ou desc |
Exemplo:
GET /empresas/?page=1&limit=10&estado=SC&ordem=nome&direcao=asc
Parâmetros inválidos ou desconhecidos retornam 422. A resposta informa
page, limit, total de registros e pages com o total de páginas.
git clone https://github.com/flpksh/api-cnpj-fastapi.gitcd api-cnpj-fastapiCopie o arquivo de exemplo:
cp .env.example .envPreencha o .env com os dados do banco e uma chave secreta:
DB_HOST=localhost
DB_PORT=5433
DB_USER=postgres
DB_PASSWORD=postgres
DB_NAME=cnpj_db
SECRET_KEY=
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=60Crie e ative um ambiente virtual, instale as dependências e aplique as migrações:
python -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
alembic upgrade headInicie a API:
uvicorn main:app --reloadA aplicação fica disponível em:
http://localhost:8000
Depois de configurar o .env, inicie a API e o PostgreSQL:
docker compose up --buildA API fica disponível em http://localhost:8000 e o PostgreSQL é exposto na
porta 5434 da máquina local.
O Compose exige uma SECRET_KEY preenchida e não inicia com um placeholder de
desenvolvimento. O container da API executa como usuário sem privilégios e usa
/health/ready para informar seu estado ao Docker.
Swagger
http://localhost:8000/docs
ReDoc
http://localhost:8000/redoc
A API utiliza autenticação baseada em JWT Bearer Token. A chave JWT deve
ter pelo menos 32 caracteres e pode ser gerada com
python -c "import secrets; print(secrets.token_hex(32))".
Novos usuários precisam informar um identificador de 3 a 50 caracteres, usando letras, números, ponto, hífen ou sublinhado. A senha deve ter entre 15 caracteres e 72 bytes. Novos hashes usam Argon2id; hashes bcrypt existentes são migrados automaticamente após um login válido.
Fluxo de autenticação:
- Registrar um usuário
- Realizar login
- Receber o Access Token
- Informar o token no botão Authorize do Swagger
- Consumir os endpoints protegidos
A maioria das operações da API retorna respostas padronizadas. O login retorna diretamente o token de acesso, conforme descrito na documentação OpenAPI.
{
"success": true,
"message": "Operação realizada com sucesso.",
"data": {}
}{
"success": false,
"message": "Empresa não encontrada.",
"data": null
}- Arquitetura em camadas (Routes, Services e Repositories)
- Repository Pattern
- Separação entre regras de negócio e acesso a dados
- Autenticação JWT
- Tratamento global de exceções
- Soft Delete
- Auditoria de registros
- Paginação, filtros e ordenação
- Documentação automática com Swagger/OpenAPI
- Migrações de banco com Alembic
- Conteinerização com Docker
- Health checks de liveness e readiness
- Logs correlacionados por
X-Request-ID - Rate limiting de tentativas de login
- Testes automatizados com Pytest
- Cobertura mínima de 85%
- Deploy em ambiente cloud
- Observabilidade com Prometheus e Grafana
- Cache com Redis
- Cobertura de testes ampliada
- Entrega contínua (CD)
Instale as dependências de desenvolvimento:
python -m pip install -r requirements-dev.txtExecute os testes:
pytest --cov --cov-report=term-missingExecute as mesmas verificações utilizadas pela integração contínua:
black --check .
isort --check-only .
ruff check .
mypy .
pytest -vO workflow está definido em .github/workflows/ci.yml e é executado em pushes e
pull requests direcionados à branch main.
O limite padrão de login é de 5 tentativas por endereço em 60 segundos. Em execuções com múltiplas instâncias, substitua o armazenamento em memória por um backend compartilhado, como Redis.
Por padrão, a API usa 8000 e o PostgreSQL usa 5434 na máquina local. As
portas podem ser alteradas por API_HOST_PORT e DB_HOST_PORT no .env.
A combinação (usuario_id, cnpj) é única: usuários diferentes podem cadastrar
a mesma empresa sem quebrar o isolamento de propriedade.
Luis Felipe
Desenvolvedor Backend focado em Python, FastAPI, APIs REST e arquitetura de software.