Interrupção antecipada e ramificação
Use MapWhen, UseWhen e middleware terminal para ramificar ou encerrar o pipeline com base nas condições da requisição.
Interrupção antecipada e ramificação é uma aula grátis de C# Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C# Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C# Academy inclui 4 aulas no total.
Ramificação e interrupção antecipada
Nem toda requisição deve percorrer todo o fluxo de processamento de componentes intermediários. O ASP.NET Core oferece ferramentas para criar ramificações, encaminhando subconjuntos para fluxos diferentes, e para interromper antecipadamente, parando o processamento e retornando imediatamente.
Map: ramificação permanente por caminho
Map cria uma ramificação permanente — as requisições que correspondem ao prefixo entram na ramificação e NUNCA retornam ao fluxo principal.
app.Map("/api", apiApp =>
{
apiApp.UseAuthentication();
apiApp.UseAuthorization();
apiApp.Run(async ctx =>
await ctx.Response.WriteAsync("API branch"));
});
// Requests to /api/... enter the branch above.
// Requests to /public/... skip the branch entirely.
app.Run(async ctx =>
await ctx.Response.WriteAsync("Main pipeline"));MapWhen: ramificação por predicado
MapWhen cria uma ramificação com base em qualquer condição, como cabeçalhos, parâmetros de consulta ou lógica personalizada. Assim como em Map, a ramificação é permanente — ela não se reúne novamente ao fluxo principal.
// Branch when a specific header is present
app.MapWhen(
ctx => ctx.Request.Headers.ContainsKey("X-Internal"),
internalApp =>
{
internalApp.UseMiddleware<InternalApiMiddleware>();
internalApp.Run(async ctx =>
await ctx.Response.WriteAsync("Internal route"));
});
// Branch on query parameter
app.MapWhen(
ctx => ctx.Request.Query.ContainsKey("legacy"),
legacyApp => legacyApp.UseMiddleware<LegacyHandlerMiddleware>());UseWhen: ramificação condicional que se reúne novamente
UseWhen é semelhante a MapWhen, mas a ramificação se reúne novamente ao fluxo principal depois de ser concluída. Isso permite adicionar componentes intermediários condicionalmente, sem criar uma bifurcação permanente.
// Log only for authenticated API calls; public routes not logged
app.UseWhen(
ctx => ctx.Request.Path.StartsWithSegments("/api")
&& ctx.User.Identity?.IsAuthenticated == true,
loggedApp =>
{
loggedApp.UseMiddleware<AuditMiddleware>();
});
// All requests continue here after the branch
app.UseRouting();
app.MapControllers();Interrupção antecipada sem chamar o próximo componente
Qualquer componente intermediário pode interromper antecipadamente o fluxo escrevendo a resposta e não chamando next. O fluxo para nesse ponto, e a resposta é retornada ao cliente.
app.Use(async (ctx, next) =>
{
// IP allowlist check
var ip = ctx.Connection.RemoteIpAddress?.ToString();
var allowed = new[] { "127.0.0.1", "::1", "10.0.0.0/8" };
if (!IsAllowed(ip, allowed))
{
ctx.Response.StatusCode = 403;
await ctx.Response.WriteAsJsonAsync(
new { error = "Access denied from this IP" });
return; // short-circuit
}
await next(ctx); // proceed
});ShortCircuit() no .NET 8
No .NET 8, MapShortCircuit e o método de extensão ShortCircuit() nos pontos de extremidade oferecem um caminho declarativo e altamente otimizado para a interrupção antecipada.
// Reject known bad paths immediately — skip entire pipeline
app.MapShortCircuit(404, "robots.txt", "favicon.ico");
// Or on a specific endpoint:
app.MapGet("/health", () => "OK")
.ShortCircuit(); // skips auth, rate limiting, etc.
// 'Run' middleware also short-circuits:
app.Map("/old-api", old =>
old.Run(ctx =>
{
ctx.Response.StatusCode = 301;
ctx.Response.Headers.Location = "/api/v2";
return Task.CompletedTask;
}));Componente intermediário terminal versus roteamento de pontos de extremidade
Antes do .NET 3, app.Run() era a única opção terminal. Agora, o roteamento de pontos de extremidade, como MapGet e MapControllers, é preferível — ele participa da autorização, da limitação de taxa e dos metadados.
// OLD: terminal middleware
app.Run(async ctx => {
if (ctx.Request.Path == "/ping")
await ctx.Response.WriteAsync("pong");
});
// PREFERRED: endpoint routing
app.MapGet("/ping", () => "pong")
.WithTags("Health")
.AllowAnonymous()
.RequireRateLimiting("basic");Detalhes da correspondência de caminhos
Map("/api") corresponde a /api e /api/anything. O caminho correspondente é removido de Request.Path dentro da ramificação e colocado em Request.PathBase.
app.Map("/api", apiApp =>
{
apiApp.Use(async (ctx, next) =>
{
// Path in branch: /users/42 (prefix removed)
Console.WriteLine(ctx.Request.Path); // /users/42
Console.WriteLine(ctx.Request.PathBase); // /api
await next(ctx);
});
apiApp.MapGet("/users/{id}", (int id) => id);
});Combinação de padrões de ramificação
Aplicações reais combinam Map, UseWhen e interrupções antecipadas para criar fluxos de processamento em camadas: as rotas públicas são leves, as rotas da API têm autenticação e as rotas administrativas têm verificações adicionais.
// Public area — no auth
app.Map("/public", pub =>
{
pub.MapGet("/health", () => "OK");
pub.MapGet("/docs", () => "Documentation");
});
// API area — full auth + rate limiting
app.Map("/api", api =>
{
api.UseAuthentication();
api.UseAuthorization();
api.UseRateLimiter();
api.MapControllers();
});
// Admin area — require admin role
app.Map("/admin", admin =>
{
admin.UseAuthentication();
admin.UseAuthorization();
admin.MapControllers().RequireAuthorization("AdminPolicy");
});Na prática: componente intermediário para teste A/B
Um componente intermediário de teste A/B encaminha as requisições para manipuladores diferentes com base em um cookie ou cabeçalho, sem modificar o código do ponto de extremidade.
app.UseWhen(
ctx => ctx.Request.Cookies.TryGetValue("ab-group", out var g) && g == "B",
betaApp =>
{
betaApp.Use(async (ctx, next) =>
{
ctx.Items["IsGroupB"] = true;
await next(ctx);
});
});
// Endpoint reads the flag:
app.MapGet("/products", (HttpContext ctx, ProductService svc) =>
{
bool isB = ctx.Items.ContainsKey("IsGroupB");
return isB ? svc.GetNewLayoutAsync() : svc.GetOldLayoutAsync();
});Verificação rápida
Qual é a principal diferença entre MapWhen e UseWhen?
Recapitulação: interrupção antecipada e ramificação
Principais conclusões:
Map: ramificação permanente baseada no caminho, sem reunião ao fluxo principalMapWhen: ramificação permanente baseada em predicadoUseWhen: ramificação condicional que se reúne novamente ao fluxo principal- Interrupção antecipada: não chame
next; escreva a resposta e retorne ShortCircuit()(.NET 8): pontos de extremidade terminais declarativos e otimizados- Combine ramificações para criar fluxos em camadas: público / API / administrativo
Perguntas Frequentes
A aula “Interrupção antecipada e ramificação” é grátis?
Sim — o texto completo de “Interrupção antecipada e ramificação” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C# Academy, atualize para CoddyKit PRO. O curso de C# Academy inclui 4 aulas no total.
O que vou aprender em “Interrupção antecipada e ramificação”?
Use MapWhen, UseWhen e middleware terminal para ramificar ou encerrar o pipeline com base nas condições da requisição. Você pratica C# Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar C# Academy?
Nenhuma experiência prévia é necessária. C# Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Interrupção antecipada e ramificação”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de C# Academy?
Sim. Cada aula de C# Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Visão geral do pipeline do ASP.NET Core
- Escrevendo middleware personalizado
- Interrupção antecipada e ramificação
- Ordenação do middleware e middleware integrado