0Pricing
C# Academy · Aula

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 principal
  • MapWhen: ramificação permanente baseada em predicado
  • UseWhen: 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

  1. Visão geral do pipeline do ASP.NET Core
  2. Escrevendo middleware personalizado
  3. Interrupção antecipada e ramificação
  4. Ordenação do middleware e middleware integrado
← Voltar para C# Academy