NET 7 -  Mininal APIs : Apresentando filtros


   Aproveite os filtros das Minimal APIs na ASP.NET Core 7 para modificar objetos de request e response ou aplicar um curto-circuito (short-circuit) no pipeline de processamento do request.

A ASP.NET Core 6 introduziu um modelo de hospedagem simplificado que nos permite construir APIs leves com dependências mínimas. As APIs mínimas (Minimal APIs) na ASP.NET Core 6 não usam controladores e não têm suporte para vários recursos úteis do ASP.NET. Um desses recursos ausentes são os filtros.

No entanto, com a ASP.NET Core 7 (disponível na release candidate 2), podemos aproveitar a interface IEndpointFilter recém-introduzida para incorporar filtros em nossas APIs mínimas. Esses filtros podem ser usados para modificar os objetos request e response conforme desejado ou para provocar um curto-circuito no pipeline de processamento de solicitação.

Nota: Cada middleware pode manipular as solicitações recebidas e passar a execução para o próximo middleware para processamento adicional. Mas um componente de middleware pode decidir não chamar a o próximo middleware no pipeline. Isso é chamado de curto-circuito ou encerrar o pipeline de solicitação.

O que são filtros? Por que devemos usá-los?

Os filtros permitem que você execute código em determinados estágios do pipeline de processamento de solicitação. Em outras palavras, um filtro é um pedaço de código que é executado antes ou depois de um método Action ser executado. Por exemplo, você pode usar um filtro para registrar sempre que alguém acessar uma página da Web ou para validar os parâmetros de solicitação enviados a um endpoint.

Benefícios dos filtros:

Por que devemos usar filtros em APIs mínimas?

Você pode aproveitar os filtros em APIs mínimas para escrever código que pode fazer o seguinte:

A interface IEndPointFilter

Você pode aproveitar a interface IEndPointFilter para modificar a solicitação ou resposta ou para provocar um curto-circuito no pipeline de processamento de solicitação. Você também pode adicionar preocupações transversais, como autenticação, autorização e registro. Em uma rápida olhada, aqui está o que você pode conseguir usando esta interface:

Interface IEndPointFilter:

namespace Microsoft.AspNetCore.Http;
public interface IEndpointFilter
{
    ValueTask<object?> InvokeAsync(
        EndpointFilterInvocationContext context,
        EndpointFilterDelegate next);
}

Assim veremos como trabalhar com filtros de manipulador de rotas ao criar Minimal APIs na ASP.NET Core 7.

Recursos usados :

Criando o projeto no VS 2022

Abra o VS 2022 preview e clique em Create a New Project selecionando o template ASP.NET Core Web API” :

Informe o nome Api_Filters;

A seguir defina as demais configurações conforme mostrada na imagem a seguir:

Ao clicar em Create teremos a minimal API criada.

Vamos alterar o código gerado pelo template criando um novo endpoint onde vamos

app.MapGet("/filters", (string chaveSecreta) =>
{
    return "Usando filtros em Minimal Apis";
})
.AddEndpointFilter(async (context, next) =>
{
    if (!context.HttpContext.Request
        .QueryString.Value.Contains("numsey"))
    {
        return Results.BadRequest();
    }
    return await next(context);
});

Os filtros podem ser registrados fornecendo um Delegate que recebe um EndpointFilterInvocationContext e retorna um EndpointFilterDelegate. O EndpointFilterInvocationContext fornece acesso ao HttpContext da solicitação e uma lista de Argumentos indicando os argumentos passados ao manipulador na ordem em que aparecem na declaração do manipulador.

Com isso em mente vamos entender o código usado:

Definimos a chamada ao método de extensão AddEndpointFilter para adicionar um filtro ao endpoint :

app.MapGet("/filters", (string chaveSecreta) =>
{
    return "Usando filtros em Minimal Apis";
})

.AddEndpointFilter(async (context, next) =>
{
    if (!context.HttpContext.Request
        .QueryString.Value.Contains("numsey"))
    {
        return Results.BadRequest();
    }
    return await next(context);
});

Que vai exibir o texto  'Usando filtros em Minimal Apis'.

O método AddEndpointFilter usa next como EndpointFilterDelegate e context como EndpointFilterInvocationContext para invocar o próximo filtro no pipeline ou o delegate do request se o último filtro tiver sido invocado.

O filtro é executado antes do manipulador do endpoint.

Quando várias invocações de AddEndpointFilter são feitas em um manipulador:

Executando o projeto teremos os endpoints exibidos no Swagger:

Acionando o endpoint  GET /filters teremos:

Como informarmos a chave secreta correta teremos resultado abaixo :

Informando qualquer outro valor teremos um Bad Request como resposta :

Neste exemplo temos um exemplo de filtro que executa antes do endpoint e valida os parâmetros usados.

Como exemplo de curto circuito podemos definir um endpoint

app.MapGet("/curto-circuito", () => "Nunca será executado...")
    .AddEndpointFilter<ShortCircuit>();

E implementar a interface IEndpointFilter e definir condição para evitar a execução do endpoint :

public class ShortCircuit : IEndpointFilter
{
    public ValueTask<object?> InvokeAsync(
        EndpointFilterInvocationContext context,
        EndpointFilterDelegate next)
    {
        return new ValueTask<object?>
            (Results.Json(new { Curto = "Circuito" }));
    }
}

E estamos conversados...

Pegue o projeto aqui :  Api_Filters.zip

Referências:


José Carlos Macoratti