Backend · REST API · Projeto educacional

ToDo API

Uma API de gerenciamento de tarefas construída para aplicar Clean Architecture, autenticação JWT e boas práticas do ecossistema .NET.

Um projeto de estudo em evolução que reúne identidade, autorização, casos de uso, persistência, configuração e containers em uma única solução backend.

Visão geral

O projeto

O domínio é simples de propósito: assim, o estudo pode se concentrar nas decisões que sustentam uma API organizada.

Mais do que um CRUD

ToDo API é uma API REST para gerenciamento de usuários e tarefas. A solução usa ASP.NET Core, autenticação JWT, autorização por roles, MediatR e Entity Framework Core em camadas inspiradas na Clean Architecture.

Finalidade educacional

O objetivo é transformar conceitos estudados separadamente em uma aplicação coerente, exercitando dependências, contratos, regras, persistência e execução de forma semelhante às preocupações de um projeto real.

Motivação

Por que construí este projeto?

Desenvolvi o ToDo API para transformar conceitos estudados separadamente em uma aplicação backend completa e organizada. A ideia não era apenas criar endpoints de tarefas, mas entender como autenticação, autorização, regras de negócio, persistência, casos de uso, configuração e infraestrutura se conectam em um projeto ASP.NET Core.

Escolhi um domínio conhecido para direcionar a atenção ao que realmente queria exercitar: separação de responsabilidades, proteção de endpoints, identificação do usuário autenticado, comunicação entre camadas, testabilidade e execução reproduzível.

O projeto também funciona como espaço de revisão. As limitações encontradas fazem parte do aprendizado e ajudam a transformar decisões implícitas em próximos passos concretos.

  • Organização das dependências
  • Autenticação e autorização
  • Casos de uso isolados
  • Persistência com EF Core
  • Configuração externa
  • Manutenibilidade e testes

Objetivos

O que eu quis consolidar

A arquitetura busca criar uma base compreensível para evolução, sem afirmar que o projeto está pronto para produção.

01

API e contratos

ASP.NET Core, REST, controllers enxutos, DTOs, códigos HTTP e Swagger/OpenAPI.

02

Arquitetura

Separação de responsabilidades, Dependency Injection, MediatR, commands, queries e handlers.

03

Identidade

JWT, claims, identificação do usuário autenticado e autorização baseada nas roles Admin e User.

04

Dados e ambiente

Entity Framework Core, PostgreSQL, migrations, variáveis de ambiente, Docker e Docker Compose.

Stack confirmada

Tecnologias utilizadas

Plataforma

C#.NET 10ASP.NET Core Web APIDependency Injection

Aplicação

MediatRFluentValidationAutoMapperDTOs

Dados e segurança

EF CorePostgreSQLJWTClaimsRoles

Execução e qualidade

DockerDocker ComposeSwaggerxUnitMoqFluentAssertions

Organização interna

Arquitetura

A solução contém cinco projetos de execução. O domínio permanece independente dos detalhes de HTTP, banco, Swagger e Docker.

EntradaTodo.Apireferencia CrossCutting
ComposiçãoToDo.CrossCuttingreferencia Application, Domain e Infrastructure
Casos de usoToDo.Applicationreferencia Domain
Detalhes externosToDo.Infrastructurereferencia Application e Domain
NúcleoToDo.Domainnão referencia outros projetos da solução

Estrutura real

ToDo.slnx
├── Todo.Api/
├── ToDo.Application/
├── ToDo.Domain/
├── ToDo.Infrastructure/
├── CrossCutting/
└── ToDo.Tests/
    ├── ToDo.Api.Tests/
    ├── ToDo.Application.Tests/
    ├── ToDo.Domain.Tests/
    └── ToDo.Infrastructure.Tests/

O projeto CrossCutting atua como composição: registra Application e Infrastructure e executa migrations/seeding na inicialização.

01 · Entrada

Todo.Api

  • Controllers e respostas HTTP
  • Autenticação e autorização
  • Middlewares e Swagger
  • Inicialização da aplicação

02 · Casos de uso

ToDo.Application

  • Commands, queries e handlers
  • DTOs, interfaces e AutoMapper
  • Validações com FluentValidation
  • Orquestração por MediatR

03 · Núcleo

ToDo.Domain

  • Entidades User e Todo
  • Value Objects e regras
  • Roles Admin e User
  • DomainException

04 · Detalhes

ToDo.Infrastructure

  • AppDbContext e Npgsql
  • Repositórios e serviços
  • Configurações de entidades
  • Migrations e autenticação JWT

05 · Composição

CrossCutting

  • Registro do MediatR
  • Validators e AutoMapper
  • Injeção das implementações
  • Migrations e seed inicial

Do HTTP ao banco

Como uma requisição percorre a aplicação

ClienteAuthControllerLoginCommandMediatRLoginHandlerIAuthServiceUserRepositoryPostgreSQL
  1. A API recebe e interpreta a requisição HTTP.
  2. O controller cria um command ou query com o contrato necessário.
  3. O MediatR encontra o handler correspondente.
  4. O handler delega a regra ao serviço de aplicação.
  5. A implementação de Infrastructure consulta ou persiste dados.
  6. O resultado retorna ao controller, que define a resposta HTTP.
Ver o fluxo de tarefas implementado no código

O fluxo de criação já possui classes reais, mas sua entrada HTTP depende da correção do controller:

TasksController
  → AddToDoCommand
  → AddToDoHandler
  → ITodoService
  → ITodoRepository
  → AppDbContext
  → PostgreSQL

Identidade e acesso

Autenticação e autorização

Autenticação confirma quem faz a requisição; autorização verifica se essa identidade pode executar a operação.

1

Cadastro ou login

Credenciais entram por AuthController e são validadas.

2

Token

O serviço gera um JWT após verificar a senha armazenada com hash.

3

Claims

O token contém NameIdentifier, Email, Name e Role.

4

Autorização

O middleware valida o token e os atributos [Authorize] aplicam as restrições.

Header de uma rota protegida

Authorization: Bearer {token}

Roles confirmadas

AdminUser

NameIdentifier conecta a identidade às operações do próprio usuário. Role diferencia ações administrativas das ações autenticadas comuns. Não há refresh token no estado atual.

Controle de acesso confirmado no código
OperaçãoUserAdmin
Atualizar ou excluir a própria contaSimSim
Listar usuáriosNãoSim
Cadastrar outro administradorNãoSim
Atualizar ou excluir outro usuárioNãoSim
Gerenciar as próprias tarefasRegra implementada*Regra implementada*

* O serviço restringe cada consulta pelo identificador da claim, mas a entrada HTTP de tarefas ainda precisa ser incluída no projeto compilado.

Contratos HTTP

Principais endpoints

Rotas e códigos de sucesso foram conferidos diretamente nos controllers.

Autenticação · endpoints ativos
MétodoRotaObjetivoAcessoSucesso
POST/api/Auth/loginAutenticar e emitir JWTPúblico200
POST/api/Auth/registerCadastrar usuário com role UserPúblico201
POST/api/Auth/register/adminCadastrar administradorAdmin201
Usuários · endpoints ativos
MétodoRotaObjetivoAcessoSucesso
GET/api/UsersListar usuáriosAdmin200
PUT/api/Users/{id}Atualizar outro usuárioAdmin204
PUT/api/UsersAtualizar a própria contaAutenticado204
DELETE/api/Users/{id}Excluir outro usuárioAdmin204
DELETE/api/UsersExcluir a própria contaAutenticado204
Tarefas · controller implementado, integração pendente

O arquivo define as rotas abaixo com [Authorize], mas está fora do diretório do projeto compilado. Elas representam a intenção já codificada, não a superfície HTTP disponível no build atual.

MétodoRota codificadaObjetivoSucesso
POST/api/TasksCriar tarefa do usuário201
GET/api/TasksListar tarefas do usuário200
GET/api/Tasks/{id}Consultar uma tarefa própria200
PUT/api/Tasks/{id}Atualizar uma tarefa própria204
DELETE/api/Tasks/{id}Excluir uma tarefa própria204
DELETE/api/TasksExcluir todas as tarefas próprias204

Dados e contratos

Persistência, DTOs e validações

PERSISTÊNCIA

EF Core + PostgreSQL

AppDbContext expõe Users e Todos. Npgsql conecta a aplicação ao PostgreSQL, migrations versionam o esquema e repositórios assíncronos isolam as consultas.

CONTRATOS

DTOs + AutoMapper

DTOs controlam entradas e saídas sem expor diretamente as entidades. Isso reduz overposting e permite que contratos HTTP e domínio evoluam com responsabilidades distintas.

VALIDAÇÃO

FluentValidation + Value Objects

Validators verificam os DTOs; Value Objects reforçam regras no domínio. Título é obrigatório e limitado a 100 caracteres, descrição a 500, email precisa ser válido e senha exige ao menos oito caracteres e diversidade de tipos.

ERROS

Middleware centralizado

ExceptionMiddleware converte exceções conhecidas em 400, 401, 404 ou 422 e mantém 500 como fallback. A resposta atual usa { status, error }; ainda não há ProblemDetails.

Ambiente

Docker, configuração e Swagger

O repositório fornece um caminho reproduzível para executar API e banco, mas ainda possui ajustes de robustez mapeados.

OrquestraçãoDocker Compose
AplicaçãoToDo APIporta 8080
DadosPostgreSQL 15volume pgdata
Variáveis de ambiente
DB_HOST=db
DB_PORT=5432
DB_NAME=postgres
DB_USER=postgres
DB_PASSWORD=change-me
JWT_KEY=change-me-with-a-long-random-value

No Compose atual, JWT_KEY do arquivo .env é mapeada para a chave ASP.NET JWT:Key. O arquivo real deve permanecer fora do Git e nunca conter segredos publicados.

Execução local
git clone https://github.com/SIRSoares33/ToDoApi.git
cd ToDoApi
dotnet restore ToDo.slnx

export DatabaseConnection="Host=localhost;Port=5432;Database=postgres;Username=postgres;Password=change-me"
export JWT__Key="change-me-with-a-long-random-value"

dotnet run --project Todo.Api/Todo.Api.csproj

Na configuração local do ASP.NET Core, o duplo underscore de JWT__Key representa a hierarquia JWT:Key.

Execução com Docker
docker compose up --build

O Compose publica a API em http://localhost:8080 e o PostgreSQL em 5432. A rede padrão do Compose conecta os serviços e o volume pgdata persiste o banco.

Explorando a API
http://localhost:8080/swagger

O Swagger atual permite visualizar e executar os contratos ativos. Entretanto, AddSwaggerGen() ainda não registra um esquema de segurança Bearer; por isso, o fluxo de autenticação via botão Authorize precisa ser configurado antes de testar rotas protegidas diretamente pela interface.

Biblioteca reutilizada

Psalms aplicado em um projeto prático

Psalms.AspNetCore.Auth.Jwt 4.0.0

Autenticação JWT sem repetir toda a infraestrutura

O pacote é referenciado por ToDo.Infrastructure, registrado por AddPsalmsJwtAuthentication(configuration) e utilizado por PsalmsJwtTokenService para emitir tokens.

O ToDo API serviu como cenário de aplicação para validar a biblioteca em conjunto com claims, roles e Dependency Injection. O projeto continua responsável pela verificação de credenciais e pelas regras de acesso.

Qualidade

Testes e automação

A base de testes já existe e cobre as quatro áreas da solução; ela não é apenas um item planejado.

154testes aprovados
49Domain
49Application
48Infrastructure
8API
TESTES

xUnit, Moq e FluentAssertions

Há testes de entidades, Value Objects, validators, handlers, controllers, claims, serviços e repositórios. Os testes de Infrastructure usam SQLite para exercitar o EF Core.

CI

GitHub Actions

O repositório possui workflow de restore, build e test com .NET 10, build de imagem Docker e análise CodeQL. Um workflow duplicado ainda aponta para .NET 8 e precisa ser consolidado.

Escolhas conscientes

Decisões que orientaram o projeto

Camadas

Separar regras e casos de uso dos detalhes externos para tornar dependências e responsabilidades mais visíveis.

MediatR

Representar intenções com commands e queries, reduzindo o acoplamento direto dos controllers.

DTOs

Controlar os contratos HTTP sem expor diretamente as entidades do domínio.

JWT e roles

Exercitar autenticação stateless e diferenciar operações administrativas das ações da própria conta.

PostgreSQL

Usar persistência relacional com migrations em um cenário próximo ao encontrado em aplicações backend.

Docker Compose

Padronizar a inicialização da API e do banco e manter configuração sensível fora do código.

Boas práticas confirmadas no código
Separation of ConcernsDependency InjectionControllers enxutosDTOsCommands e queriesCódigo assíncronoAutenticaçãoAutorizaçãoClaimsConfiguração externaPersistência isoladaOpenAPITestes automatizadosCI

Capacidade demonstrada

O que este projeto demonstra

O ToDo API demonstra minha capacidade de construir uma aplicação backend além dos endpoints básicos, organizando autenticação, autorização, casos de uso, persistência e infraestrutura em uma arquitetura compreensível e preparada para evolução.

  • Desenvolvimento backend com C# e ASP.NET Core
  • Modelagem de APIs REST e contratos
  • JWT, claims e autorização por roles
  • EF Core, PostgreSQL e migrations
  • MediatR, testes e organização arquitetural
  • Docker e configuração de ambiente

Reflexão

Principais aprendizados

Aprendi que uma API organizada exige mais do que endpoints funcionando. Autenticação e autorização resolvem problemas diferentes, e as claims são o elo entre a identidade do usuário e as regras da aplicação.

Separar camadas tornou as dependências mais visíveis. MediatR ajudou a isolar casos de uso, enquanto os DTOs protegeram os contratos externos. Ao mesmo tempo, o projeto mostrou que abstrações só agregam valor quando continuam proporcionais ao problema.

Docker reduziu diferenças entre ambientes, mas também evidenciou que subir containers não basta: prontidão do banco, variáveis consistentes, segredos e observabilidade precisam ser tratados explicitamente.

O aprendizado mais importante foi revisar o próprio código com honestidade. Encontrar uma rota implementada fora do projeto compilado reforçou a importância de validar a aplicação como ela realmente é executada.

Roadmap técnico

Próximos passos

Evoluções realistas identificadas a partir do estado atual, sem prazo ou promessa de produção.

  1. Integrar o controller de tarefasMover TasksController.cs para o projeto Todo.Api e adicionar testes dos endpoints compilados.
  2. Fortalecer o ambiente DockerConfigurar POSTGRES_DB/POSTGRES_USER, health check e espera real pela prontidão do banco.
  3. Completar a experiência do SwaggerRegistrar o esquema Bearer e documentar respostas e requisitos de autorização.
  4. Padronizar segurança e errosRevisar o provisionamento do administrador inicial, atualizar pacotes sinalizados e adotar ProblemDetails.
  5. Ampliar a validação integradaAdicionar testes de integração com PostgreSQL real, por exemplo usando Testcontainers, sem substituir a suíte atual.
  6. Evoluir a operaçãoConsolidar workflows, incluir logs estruturados, health checks, paginação, filtros, versionamento e rate limiting conforme a necessidade.