Se você vem do Node.js, Python ou PHP, o nome “.NET” pode parecer algo pesado e corporativo. Mas a real é que o ASP.NET Core se tornou um dos frameworks mais versáteis do mercado. Ele é open-source, roda em qualquer lugar (Windows, Linux, Mac) e oferece uma performance que bate de frente com as linguagens mais rápidas da atualidade.
Vamos abrir o capô do ASP.NET e entender como ele organiza as coisas, sem preconceitos entre estilos de código.
O Coração do Sistema: O C# e o SDK
Antes de falar de web, entenda que o C# é a linguagem e o .NET SDK é o kit de ferramentas que compila e roda tudo. A grande vantagem aqui é a tipagem forte: o compilador é seu primeiro “revisor de código”, evitando que você tente acessar uma propriedade que não existe ou passe um texto onde deveria ser um número.
As Duas Portas de Entrada: Minimal APIs e Controllers
No ASP.NET moderno, você tem dois caminhos principais para criar seus endpoints. Ambos são profissionais, estáveis e suportados pela Microsoft.
1. Minimal APIs
Introduzidas nas versões mais recentes, elas permitem que você crie rotas com pouquíssimas linhas. É ideal para microsserviços ou para quem gosta de ver tudo em um lugar só, sem muita hierarquia de pastas.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// Uma rota direta e simples
app.MapGet("/v1/hello", () => new { message = "Hello world, .NET!" });
app.Run();
2. Controllers
É o padrão clássico do MVC. Se o seu projeto vai ter dezenas de rotas e regras de negócio complexas, os Controllers ajudam a separar as responsabilidades por arquivos. Cada classe cuida de um “assunto” do sistema.
[ApiController]
[Route("v1/...")]
public class UserController : ControllerBase
{
[HttpGet]
public IActionResult List()
{
return Ok(new[] { "Hello", "World" });
}
}
Como o fluxo funciona: O Pipeline de Middleware
Quando o cliente faz um pedido (HTTP), ele não cai direto no seu código. Ele passa por uma série de “estações” chamadas Middlewares.
- A Requisição chega: O servidor web (Kestrel) recebe o pacote.
- Middlewares de Ida: O código passa por validações de segurança, logs e autenticação. Se algo estiver errado (ex: usuário não logado), para ali mesmo e devolve um erro.
- O seu Código (Endpoint): Se tudo estiver ok, a requisição chega no seu método (seja Minimal API ou Controller). Você processa, busca no banco e gera a resposta.
- Middlewares de Volta: A resposta faz o caminho inverso, podendo ser compactada ou modificada antes de sair para o cliente.
Injeção de Dependência: O “Garçom” do Sistema
Um dos pontos mais fortes do ASP.NET, que assusta iniciantes mas salva vidas, é a Injeção de Dependência (DI).
Em vez de você dar um new BancoDeDados() dentro de cada função, você avisa ao ASP.NET no início do projeto: “Olha, sempre que alguém precisar de banco de dados, entregue esta configuração aqui”. O framework gerencia a criação e a destruição desses objetos para você. Isso deixa o código absurdamente mais fácil de testar e manter.
Na Prática (Model, Service e Controller)
Para o sistema não virar uma bagunça, o ASP.NET sugere uma divisão de tarefas. Imagine que você está criando um sistema de usuários. Em vez de colocar tudo no mesmo arquivo, dividimos assim:
- Model: É o formato dos dados (a planta baixa).
- Service: É onde o “cérebro” do sistema fica (a regra de negócio).
- Controller: É o porteiro que recebe a requisição e entrega para o Service.
Veja como esse trio trabalha junto:
1. O Model
// Simples e direto: o que um usuário tem?
public record User(int Id, string Name, string Email);
2. O Service
Aqui é onde você faria um cálculo, validaria um dado ou salvaria no banco. Usamos uma Interface para que o sistema seja fácil de testar depois.
public interface IUserService {
List<User> ListAll();
}
public class UserService : IUserService {
public List<User> ListarTodos() {
// Finja que isso veio do banco de dados
return new List<User> {
new User(1, "Você Dev", "contato@dev.com"),
new User(2, "Dev Leigo", "aprendiz@dotnet.com")
};
}
}
3. O Controller (A conexão com o mundo)
O Controller não sabe como os usuários são listados, ele apenas pede ao Service e entrega o resultado.
[ApiController]
[Route("v1/users")]
public class UserController : ControllerBase {
private readonly IUserService _service;
// O ASP.NET entrega o Service pronto aqui via Injeção de Dependência
public UserController(IUserService service) {
_service = service;
}
[HttpGet]
public IActionResult Get() {
var list = _service.ListAll();
return Ok(list); // Retorna 200 OK com o JSON automático
}
}
O Fluxo: Quem manda em quem?
Para você não se perder, montei essa tabela rápida de responsabilidades. É o que eu sigo para manter o Clean Code em dia:
| Peça | O que ela faz? | O que ela NÃO deve fazer? |
| Controller | Valida se a rota existe e responde ao cliente. | Nunca deve ter lógica de banco ou cálculos. |
| Service | Faz cálculos, valida regras e chama o banco. | Não sabe se a requisição veio da Web ou de um robô. |
| Model | Define como os dados aparecem. | Não deve ter lógica nenhuma, apenas propriedades. |
No fim das contas…
O ASP.NET Core não tenta te prender a uma única forma de trabalhar. Quer algo rápido e direto? Vá de Minimal APIs. Precisa de uma estrutura robusta para um time grande? Use Controllers com Services.
O importante é entender que, por trás da sintaxe, existe um sistema de pipeline e injeção de dependência que garante que sua aplicação seja escalável desde o primeiro dia. Se você já tem uma base de lógica de programação, o próximo passo é baixar o SDK e rodar o seu primeiro dotnet watch para ver a mágica acontecer em tempo real.