API REST para autenticação, carteira, cotações, dashboard, rate limiting e health check
Live Swagger (produção): https://investapi-fhu5.onrender.com/swagger/index.html
InvestAPI é uma API REST para gerenciamento de investimentos com foco em simplicidade. Ela entrega autenticação com JWT, cadastro e gestão de usuários, carteira de ativos, lançamentos de transações, atualização de cotações, dashboard consolidado, rate limiting global e health check para monitoramento.
As cotações externas vêm da Brapi para ações e da CoinGecko para criptomoedas.
- Autenticação com registro e login via JWT
- Carteira com ativos e transações
- Cotações externas com cache
- Dashboard com resumo, performance e alocação
- Rate limiting para proteger a API
- Health check para verificar disponibilidade
- .NET 10
- ASP.NET Core Web API
- Entity Framework Core
- SQLite
- JWT Bearer
- BCrypt.Net-Next
- FluentValidation
- Swagger/OpenAPI
- HttpClientFactory
- Rate Limiting do ASP.NET Core
Padrão: MVC com Repository Pattern (Layered Architecture)
HTTP Request
↓
Controllers (DTOs de entrada)
↓
Services (Lógica de negócio)
↓
Repositories / DbContext (Acesso a dados)
↓
Database
- Controllers — Endpoints HTTP, validação de entrada com FluentValidation
- Services — Lógica de negócio isolada (Auth, Portfolio, Cotações, etc)
- Repositories — Abstração de acesso a dados (Assets, Transactions)
- Models — Entidades do banco (Users, Assets, Transactions)
- DTOs — Transferência de dados entre client/server
- Data — Entity Framework Core + DbContext
- Middleware — Tratamento global de exceções
- Validators — Regras de validação de entrada
Este projeto usa uma arquitetura em camadas simples porque fica mais fácil de entender e manter. Os services acessam o DbContext e os repositories sem criar muitas abstrações extras. Para um projeto pequeno ou de portfólio, esse formato deixa o código mais direto.
Se o sistema crescer, aí vale separar melhor em use cases e camadas mais rígidas.
- .NET 10 SDK
- SQLite usa arquivo local no projeto; no Render, aponte para um disco persistente
- Copie o arquivo de exemplo:
cp .env.example .env- Edite o arquivo
.envcom suas credenciais:
ConnectionStrings__DefaultConnection=Data Source=investapi.db
JwtSettings__SecretKey=sua_chave_secreta_com_minimo_32_bytes
QuoteSettings__BrapiToken=seu_token_da_brapi
Cors__AllowedOrigins=http://localhost:3000,http://localhost:5173.env — ele está no .gitignore.
# Clone o repositório
git clone https://github.com/mapompeo/InvestAPI.git
cd InvestAPI
# Instale as dependências
dotnet restore
# Rode a aplicação
dotnet runA API fica disponível nas portas definidas em InvestAPI/Properties/launchSettings.json e o Swagger aparece em /swagger.
Swagger pública: https://investapi-fhu5.onrender.com/swagger/index.html
| Variável | Descrição | Padrão |
|---|---|---|
ConnectionStrings__DefaultConnection |
String de conexão do SQLite | Data Source=investapi.db |
JwtSettings__SecretKey |
Chave secreta JWT (mín. 32 bytes) | SET_THIS_IN_ENVIRONMENT_MINIMUM_32_BYTES |
JwtSettings__Issuer |
Emissor do token JWT | InvestAPI |
JwtSettings__Audience |
Público do token JWT | InvestAPI-Users |
JwtSettings__ExpirationInDays |
Tempo de expiração do token | 7 |
QuoteSettings__BrapiToken |
Token da Brapi para ações | (vazio) |
QuoteSettings__BrapiBaseUrl |
URL base da Brapi | https://brapi.dev |
QuoteSettings__CoinGeckoBaseUrl |
URL base da CoinGecko | https://api.coingecko.com |
QuoteSettings__CoinGeckoVsCurrency |
Moeda usada na consulta da CoinGecko | usd |
Cors__AllowedOrigins |
Origins separadas por vírgula | http://localhost:3000 |
RateLimiting__PermitLimit |
Quantidade máxima de requisições por janela | 120 |
RateLimiting__WindowMinutes |
Janela do rate limit em minutos | 1 |
RateLimiting__QueueLimit |
Tamanho da fila do rate limit | 0 |
SQLITE_DB_PATH |
Override do arquivo SQLite | investapi.db |
PORT |
Porta da aplicação | 5000 |
- Use um serviço Web no Render com
Docker. - Deixe o
Dockerfilena raiz do repositório. - O container já usa a porta informada pelo Render.
- O SQLite fica em
investapi.dbdentro do container. - Sem disco persistente, os dados do SQLite podem ser perdidos entre deploys.
GET /health
Accept: application/jsonPOST /api/v1/auth/login
Content-Type: application/json
{
"email": "[email protected]",
"password": "SenhaForte123!"
}GET /api/v1/dashboard
Authorization: Bearer {seu-token}
Accept: application/jsonBase path: /api/v1
| Método | Rota | Descrição |
|---|---|---|
| POST | /api/v1/auth/register |
Registra novo usuário |
| POST | /api/v1/auth/login |
Autentica e retorna JWT |
| Método | Rota | Descrição |
|---|---|---|
| GET | /api/v1/users/me |
Dados do usuário logado |
| GET | /api/v1/users/{id} |
Busca um usuário |
| PUT | /api/v1/users/{id} |
Atualiza um usuário |
| DELETE | /api/v1/users/{id} |
Remove um usuário |
| Método | Rota | Descrição |
|---|---|---|
| POST | /api/v1/assets |
Adiciona ativo |
| GET | /api/v1/assets |
Lista ativos |
| GET | /api/v1/assets/{id} |
Detalhes + histórico |
| DELETE | /api/v1/assets/{id} |
Remove ativo |
| Método | Rota | Descrição |
|---|---|---|
| POST | /api/v1/transactions |
Registra compra/venda |
| GET | /api/v1/transactions |
Lista transações |
| Método | Rota | Descrição |
|---|---|---|
| GET | /api/v1/portfolio/summary |
Resumo da carteira |
| GET | /api/v1/portfolio/performance |
Performance por ativo |
| GET | /api/v1/dashboard |
Dashboard completo |
| Método | Rota | Descrição |
|---|---|---|
| POST | /api/v1/quotes/refresh |
Atualiza todas as cotações |
| POST | /api/v1/quotes/refresh/{ticker} |
Atualiza uma cotação |
🔒 = Requer autenticação (Bearer token)
POST /api/v1/auth/register
Content-Type: application/json
{
"name": "João Silva",
"email": "[email protected]",
"password": "SenhaForte123!",
"confirmPassword": "SenhaForte123!"
}POST /api/v1/auth/login
Content-Type: application/json
{
"email": "[email protected]",
"password": "SenhaForte123!"
}Response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"email": "[email protected]",
"name": "João Silva"
}POST /api/v1/assets
Authorization: Bearer {seu-token}
Content-Type: application/json
{
"ticker": "PETR4",
"type": "Stock",
"quantity": 100,
"avgBuyPrice": 38.50
}Response:
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"ticker": "PETR4",
"currentPrice": 40.2,
"totalInvested": 3850.0,
"currentValue": 4020.0,
"profitLoss": 170.0,
"profitLossPercentage": 4.42
}- O usuário cria conta e faz login.
- A API devolve um token JWT.
- Com o token, o usuário cria ativos e transações.
- A API calcula os dados da carteira e busca cotações externas.
- Swagger: Acesse
/swaggerquando a API estiver rodando
Este projeto está sob a licença MIT. Veja o arquivo LICENSE para mais detalhes.
Matheus Pompeo
⭐ Se este projeto te ajudou, considere dar uma estrela!
Made with ❤️ and C#