Ícone do site MicroGmx

Otimização de Aplicações ASP.NET Core com Caching em Minimal APIs

{"prompt":"A holographic blueprint of a sleek ASP.NET Core Minimal API transforming into a shimmering, hyper-efficient data stream, with iridescent caching layers visualized as a rapidly expanding nebula around it..jpg","originalPrompt":"A holographic blueprint of a sleek ASP.NET Core Minimal API transforming into a shimmering, hyper-efficient data stream, with iridescent caching layers visualized as a rapidly expanding nebula around it..jpg","width":512,"height":512,"seed":66160,"model":"flux","enhance":false,"nologo":true,"negative_prompt":"undefined","nofeed":false,"safe":false,"quality":"medium","image":[],"transparent":false,"has_nsfw_concept":false,"concept":{"special_scores":{"0":0.352,"1":-0.127,"2":-0.147},"special_care":[[0,0.352]],"concept_scores":{"0":-0.086,"1":-0.135,"2":-0.098,"3":-0.088,"4":-0.137,"5":-0.084,"6":-0.087,"7":-0.118,"8":-0.117,"9":-0.16,"10":-0.094,"11":-0.117,"12":-0.093,"13":-0.104,"14":-0.11,"15":-0.146,"16":-0.095},"bad_concepts":[]}}

No universo do desenvolvimento de aplicações com ASP.NET Core, a busca por performance e escalabilidade é constante. Uma das estratégias mais eficazes para atingir esses objetivos é a implementação de caching. O caching, em sua essência, consiste em armazenar dados temporariamente para que possam ser acessados mais rapidamente em requisições futuras. Em ASP.NET Core, temos diversas opções de caching, desde as mais simples, como o in-memory caching, até as mais sofisticadas, como o distributed caching e o hybrid caching.

Tipos de Caching em ASP.NET Core

O ASP.NET Core oferece flexibilidade para o desenvolvedor escolher onde e como o cache será aplicado. Podemos optar por:

Implementando Caching em Minimal APIs

As Minimal APIs do ASP.NET Core oferecem uma forma simplificada de criar endpoints HTTP. Implementar caching nessas APIs é relativamente simples e pode trazer ganhos significativos de performance.

In-Memory Caching

Para utilizar o in-memory caching, podemos injetar a interface IMemoryCache no endpoint da API. O código abaixo demonstra como buscar dados no cache e, caso não estejam presentes, buscar no repositório, armazenar no cache e retornar:

app.MapGet("/authors/getall", (IMemoryCache cache, IAuthorRepository authorRepository) =>
{
    if (!cache.TryGetValue("get-authors", out List authors))
    {
        authors = authorRepository.GetAll();
        var cacheEntryOptions = new MemoryCacheEntryOptions()
            .SetAbsoluteExpiration(TimeSpan.FromMinutes(5))
            .SetSlidingExpiration(TimeSpan.FromMinutes(1));
        cache.Set("get-authors", authors, cacheEntryOptions);
    }
    return Results.Ok(authors);
});

Nesse exemplo, definimos um tempo de expiração absoluto de 5 minutos e um tempo de expiração deslizante de 1 minuto. Isso significa que o cache será invalidado após 5 minutos, ou após 1 minuto de inatividade.

Distributed Caching

O distributed caching é ideal para aplicações que precisam escalar horizontalmente. Para utilizá-lo, injetamos a interface IDistributedCache no endpoint da API. O exemplo a seguir mostra como implementar o distributed caching:

app.MapGet("/getallauthors", async (IDistributedCache cache) =>
{
    var cacheKey = "get-all-authors";
    var cachedMessage = await cache.GetStringAsync(cacheKey);
    if (cachedMessage == null)
    {
        cachedMessage = $"The data has been cached at {DateTime.Now}";
        await cache.SetStringAsync(cacheKey, cachedMessage, new DistributedCacheEntryOptions
        {
            AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(60)
        });
    }
    return Results.Ok(cachedMessage);
});

Neste caso, o cache expira após 60 segundos. É importante configurar corretamente a conexão com o servidor de cache distribuído, como Redis ou SQL Server, na inicialização da aplicação.

Hybrid Caching

A partir do .NET 9, o Hybrid Caching oferece uma abordagem que combina as vantagens do in-memory caching e do distributed caching. Ele pode ser configurado da seguinte forma:

services.AddHybridCache(options => {
    options.DefaultEntryOptions = new HybridCacheEntryOptions
    {
        Expiration = TimeSpan.FromMinutes(5),
        LocalCacheExpiration = TimeSpan.FromMinutes(5)
    };
});

Essa configuração define um tempo de expiração padrão de 5 minutos tanto para o cache local (in-memory) quanto para o cache distribuído.

Response Caching

O Response Caching utiliza os headers HTTP para controlar o cache no cliente. Para habilitá-lo, adicionamos o middleware de Response Caching à pipeline da aplicação:

builder.Services.AddResponseCaching();
app.UseResponseCaching();

O cliente, ao receber a resposta, poderá armazená-la em cache de acordo com os headers definidos.

Output Caching

O Output Caching permite um controle mais preciso sobre o cache no servidor. Podemos implementar o Output Caching utilizando o método CacheOutput:

app.MapPost("/author/getauthors", ([FromServices] IAuthorRepository authorRepository) =>
{
    return authorRepository.GetAll();
}).CacheOutput(x => x.Expire(TimeSpan.FromSeconds(30)));

Neste exemplo, a resposta do endpoint será armazenada em cache por 30 segundos. Ao contrário do Response Caching, o Output Caching pode ser utilizado com in-memory, distributed ou hybrid caching.

Melhores Práticas de Caching

Para obter o máximo proveito do caching em suas aplicações ASP.NET Core, siga estas melhores práticas:

Conclusão

O caching é uma ferramenta poderosa para otimizar aplicações ASP.NET Core. Ao escolher a estratégia de caching correta e seguir as melhores práticas, é possível reduzir a latência, aumentar a escalabilidade e melhorar a experiência do usuário. As Minimal APIs simplificam a implementação de caching, tornando-o acessível mesmo em projetos menores. A crescente adoção e a constante evolução das opções de caching no .NET, como a inclusão do Hybrid Cache, reforçam a importância desta técnica no desenvolvimento moderno de aplicações web. Ao implementar caching, os desenvolvedores precisam equilibrar a necessidade de dados atualizados com os benefícios de performance, ajustando os tempos de expiração e utilizando a invalidação de cache de forma inteligente. Não se trata apenas de uma otimização técnica, mas de uma consideração estratégica que pode impactar diretamente a satisfação do usuário e a eficiência da aplicação.

Sair da versão mobile