Este projeto implementa uma API em .NET 9 (Minimal APIs) com SQLite, seguindo princípios de Clean Architecture.
Inclui funcionalidades como upload de arquivo CSV, validação, processamento assíncrono, persistência em SQLite e integração com a API pública do Rick and Morty.
- Funcionalidades
- Tecnologias
- Como executar (Docker)
- Formato do arquivo CSV
- Endpoints / Rotas
- Regras de paginação
- Códigos de status do processamento
- Estrutura de pastas importante
- Upload de arquivos CSV contendo referências a episódios, personagens e localizações.
- Validação do arquivo e das linhas (formato e ordem dos campos).
- Processamento assíncrono (fila/worker) — a API retorna imediatamente um
processIdpara consulta de status. - Armazenamento dos dados processados em SQLite (pasta
/datano container). - Endpoints para consultar status e recuperar os dados processados (com paginação).
- .NET 9 (Minimal APIs)
- ASP.NET Core
- Entity Framework Core (SQLite)
- Serilog (logging)
- Docker
- Azure
docker build -t rickandmorty-app .Observação: a aplicação por padrão no
Program.csdo projeto usa a porta 5164 (ex.:options.ListenAnyIP(5164)).
Exemplo (mapeando porta 5164):
docker run -d --name rickandmorty \
-p 5164:5164 \
-v $(pwd)/data:/data \
rickandmorty-appO arquivo deve obrigatoriamente seguir este formato (primeira linha é o cabeçalho):
episode_id,character_id,character_name,location_id
12,5,Jerry Smith,20Regras:
- A primeira linha obrigatoriamente deve ser o cabeçalho com exatamente essas colunas e nessa ordem.
- Valores separados por vírgula.
- Se o arquivo tiver alguma linha inválida, a requisição será ignorada (conforme regra do projeto).
- Formatos inválidos, colunas faltando ou tipos errados invalidam o upload.
O serviço está publicado na Azure, e pode ser chamado via API REST, seguem rotas:
Faz upload do arquivo CSV (multipart/form-data).
Request (curl - exemplo Windows)
curl --request POST \
--url https://integration-rickandmorty-api-hcbubthratdde4aw.brazilsouth-01.azurewebsites.net/upload/ \
--header 'content-type: multipart/form-data' \
--form 'file=@/caminho/para/arquivo.csv'Request (curl - exemplo Linux/macOS)
curl -X POST "http://localhost:5164/upload/" -F "file=@/caminho/para/arquivo.csv"Resposta de sucesso (200 OK)
{
"message": "Upload realizado com sucesso!",
"processId": "0227fe39-e271-4c4a-b21f-7ddd52bc48ca",
"statusUrl": "/status/0227fe39-e271-4c4a-b21f-7ddd52bc48ca"
}Importante: se o arquivo for inválido (linha inválida, cabeçalho errado, etc.), a requisição é ignorada conforme comportamento implementado.
Consulta o status do processamento do arquivo.
Request (curl)
curl --request GET \
--url https://integration-rickandmorty-api-hcbubthratdde4aw.brazilsouth-01.azurewebsites.net/status/0227fe39-e271-4c4a-b21f-7ddd52bc48caResponse (200 OK) — Exemplo
{
"id": "0227fe39-e271-4c4a-b21f-7ddd52bc48ca",
"filePath": "Uploads/0227fe39-e271-4c4a-b21f-7ddd52bc48ca",
"createdTimestamp": "2025-08-09T03:07:52.1225374",
"startTime": "2025-08-09T03:07:52.1225374",
"endTime": "2025-08-09T03:08:14.120834",
"status": "CONCLUÍDO COM SUCESSO"
}Status possíveis:
RECEBIDOEM PROCESSAMENTOCONCLUÍDO COM SUCESSO
Status de erro (encerramento com falha):
ERRO - FALHA AO SALVAR DADOSERRO - FALHA AO OBTER DADOSERRO INTERNO DURANTE O PROCESSAMENTO
Retorna os dados processados referentes ao processId. Suporta paginação via query string (pageNumber e pageSize).
Request (curl)
curl --request GET \
--url 'https://integration-rickandmorty-api-hcbubthratdde4aw.brazilsouth-01.azurewebsites.net/upload/0227fe39-e271-4c4a-b21f-7ddd52bc48ca?pageNumber=1&pageSize=1'Resposta (200 OK) — Exemplo
{
"episodes": [
{
"id": "int",
"name": "string",
"air_date": "string",
"episode": "string",
"characters": [
{
"id": "int",
"name": "string",
"status": "string",
"species": "string",
"type": "string",
"gender": "string",
"origin": {
"id": "int",
"name": "string",
"type": "string",
"dimension": "string"
},
"location": {
"id": "int",
"name": "string",
"type": "string",
"dimension": "string"
}
}
]
}
],
"totalLocations": "int",
"totalFemaleCharacters": "int",
"totalMaleCharacters": "int",
"totalGenderlessCharacters": "int",
"totalGenderUnknownCharacters": "int",
"uploadeFilePath": "string"
}Nota:
uploadeFilePathsegue o formato implementado — ajuste se preferir outro campo (uploadedFilePath,uploadFilePath, etc.).
- Se
pageNumbernão vier, maspageSizevier → assumepageNumber = 1. - Se
pageNumbervier, maspageSizenão vier → assumepageSize = 10. - Ambos podem ser usados juntos:
?pageNumber=2&pageSize=20.
RECEBIDO— upload aceito e enfileirado.EM PROCESSAMENTO— worker consumindo o arquivo e populando dados.CONCLUÍDO COM SUCESSO— processamento finalizado sem erros.ERRO - FALHA AO SALVAR DADOS— falha ao persistir dados no DB.ERRO - FALHA AO OBTER DADOS— falha ao recuperar dados externos (API Rick and Morty).ERRO INTERNO DURANTE O PROCESSAMENTO— exceptions ou problemas não categorizados.
./Uploads— local (no container) onde os arquivos CSV são armazenados temporariamente../Src— código-fonte (UseCases, Ports, Adapters, Controllers/Endpoints).Dockerfile— imagem multi-stage (build + runtime).