Se você já trabalhou com APIs em .NET, provavelmente já ouviu falar sobre Middlewares. Mas afinal, o que são e por que são tão importantes?
Neste artigo, vamos explorar o conceito de Middlewares no contexto de APIs .NET, entender como eles funcionam e ver exemplos práticos de como utilizá-los.
O que são Middlewares?
Middlewares são componentes que formam o pipeline de processamento de requisições em uma aplicação .NET. Eles são responsáveis por lidar com solicitações HTTP (requests) e respostas HTTP (responses), permitindo executar lógicas antes e depois que uma requisição chegue ao seu endpoint final.
Pense em um middleware como uma "camada" que a requisição passa antes de chegar ao seu destino (e também na volta, quando a resposta é enviada ao cliente).
Analogia do Middleware
Imagine um restaurante:
- Você faz um pedido (request).
- Antes de chegar ao cozinheiro (sua API Controller), o pedido passa pelo garçom, que verifica se está completo (middleware de validação).
- Depois de pronto, o prato (response) pode passar por outro garçom que adiciona temperos extras (middleware de transformação).
Cada middleware tem uma função específica e pode interromper o fluxo se necessário.
Como os Middlewares Funcionam no .NET?
No .NET, o pipeline de middlewares é configurado no arquivo Program.cs, usando o método Use, Run ou Map.
Exemplo Básico de Middleware
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// Middleware 1: Logging
app.Use(async (context, next) =>
{
Console.WriteLine($"Requisição recebida: {context.Request.Path}");
await next(); // Chama o próximo middleware
});
// Middleware 2: Autorização
app.Use(async (context, next) =>
{
if (!context.Request.Headers.ContainsKey("Authorization"))
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync("Não autorizado");
return; // Interrompe o pipeline
}
await next();
});
// Rota principal
app.MapGet("/", () => "Hello World!");
app.Run();
Neste exemplo:
- O primeiro middleware registra o caminho da requisição.
- O segundo middleware verifica se há um header de autorização. Se não houver, retorna 401 Unauthorized.
Se tudo estiver correto, a requisição chega ao endpoint principal (/).
Middlewares Comuns no .NET
O .NET já possui vários middlewares prontos para uso:
- UseRouting() Define o roteamento da aplicação.
- UseAuthentication() Habilita autenticação.
- UseAuthorization() Habilita autorização.
- UseCors() Configura políticas CORS.
- UseStaticFiles() Permite servir arquivos estáticos (HTML, CSS, JS).
Exemplo com Middlewares Integrados
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapGet("/secure", () => "Rota segura!").RequireAuthorization();
app.Run();
A Ordem Importa!
No .NET, a sequência em que os middlewares são registrados no Program.cs define a ordem de execução. Isso é crucial, pois um middleware pode depender do processamento de outro. Por exemplo:
app.UseHttpsRedirection(); // 1º: Redireciona para HTTPS
app.UseStaticFiles(); // 2º: Serve arquivos estáticos (CSS, JS)
app.UseRouting(); // 3º: Define as rotas
app.UseAuthentication(); // 4º: Autentica o usuário
app.UseAuthorization(); // 5º: Verifica as permissões
Se você inverter UseRouting e UseAuthentication, a autenticação não funcionará, pois o roteamento ainda não terá identificado o endpoint a ser protegido.
Quando Criar um Middleware Personalizado?
Você pode criar um middleware personalizado quando:
- Precisa validar algo em todas as requisições (ex: checar API Key).
- Quer loggar todas as requisições/respostas.
- Precisa transformar respostas (ex: adicionar headers customizados).
Um uso comum é centralizar o tratamento de exceções para evitar repetição de código:
Middleware de Tratamento de Erros:
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
var error = context.Features.Get<IExceptionHandlerFeature>();
context.Response.StatusCode = 500;
await context.Response.WriteAsJsonAsync(new
{
Message = "Ocorreu um erro inesperado.",
Details = error?.Error.Message
});
});
});
Impacto na Performance
Middlewares adicionam overhead ao pipeline. Para evitar gargalos:
- Use middlewares leves (ex.: evite processamento bloqueante).
- Registre apenas os necessários (em produção, desative logs detalhados).
- Considere UseWhen para aplicar middlewares condicionalmente:
app.UseWhen(context => context.Request.Path.StartsWith("/api"), appBuilder =>
{
appBuilder.UseMiddleware<ApiSpecificMiddleware>();
});
Conclusão
Middlewares são peças fundamentais no desenvolvimento de APIs .NET, permitindo adicionar comportamentos personalizados ao pipeline de requisições. Eles podem ser usados para logging, autenticação, tratamento de erros e muito mais.
Dominar middlewares ajuda a criar aplicações mais modulares, seguras e eficientes.
Referências Úteis
Documentação Oficial: Middlewares no ASP.NET Core
E aí, já usou middlewares em seus projetos? Conte nos comentários! 🚀