No universo do desenvolvimento web com ASP.NET Core, otimizar a performance é crucial para garantir uma experiência de usuário ágil e eficiente. Uma das estratégias mais eficazes para alcançar esse objetivo é o uso de caching. Implementar caching em Minimal APIs do ASP.NET Core pode parecer complexo à primeira vista, mas, com o entendimento correto das opções disponíveis, torna-se uma ferramenta poderosa para aprimorar a escalabilidade e a resposta das suas aplicações.
Tipos de Caching em ASP.NET Core
O ecossistema ASP.NET Core oferece diversas abordagens para caching, cada uma com suas particularidades e casos de uso ideais:
- In-memory caching: Armazena dados na memória do servidor. É rápido e simples, ideal para aplicações com menor volume de dados e menor necessidade de escalabilidade.
- Distributed caching: Distribui os dados em cache por múltiplos servidores, permitindo escalabilidade horizontal. Útil para aplicações que precisam lidar com alta demanda e balanceamento de carga.
- Hybrid caching: Combina o melhor dos dois mundos, utilizando a velocidade do in-memory caching com a durabilidade e escalabilidade do distributed caching.
- Response caching: Baseia-se nos headers HTTP para armazenar respostas do servidor no cliente ou em proxies. Reduz o número de requisições ao servidor, diminuindo a latência.
- Output caching: Permite um controle mais granular do caching de respostas do servidor, possibilitando a invalidação programática e a configuração do armazenamento do cache.
Implementando Caching na Prática
A escolha do tipo de caching mais adequado depende das necessidades específicas da sua aplicação. Vejamos alguns exemplos práticos de como implementar cada um deles em Minimal APIs:
In-memory caching
Para utilizar o in-memory caching, você pode injetar a interface IMemoryCache
no seu endpoint e verificar se os dados já estão armazenados em cache. Caso contrário, busca os dados na fonte original, armazena no cache e retorna.
app.MapGet("authors/getall", (IMemoryCache cache, IAuthorRepository authorRepository) =>
{
if (!cache.TryGetValue("get-authors", out List<Author> 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);
});
Neste exemplo, os dados dos autores são armazenados em cache por um período máximo de 5 minutos, com uma expiração deslizante de 1 minuto. Isso significa que, se o cache for acessado dentro de 1 minuto, o tempo de expiração é renovado.
Distributed caching
Para o distributed caching, você pode utilizar a interface IDistributedCache
. O processo é semelhante ao in-memory caching, mas os dados são armazenados em um sistema de cache distribuído, como Redis ou SQL Server.
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, os dados são armazenados no cache distribuído por 60 segundos. A grande vantagem aqui é que, se a sua aplicação estiver rodando em múltiplos servidores, todos eles compartilharão o mesmo cache.
Hybrid caching
A partir do .NET 9, o hybrid caching oferece uma abordagem combinada, aproveitando o in-memory caching para acessos rápidos e o distributed caching para garantir a durabilidade dos dados. A configuração é feita no arquivo Program.cs
.
services.AddHybridCache(options => {
options.DefaultEntryOptions = new HybridCacheEntryOptions
{
Expiration = TimeSpan.FromMinutes(5),
LocalCacheExpiration = TimeSpan.FromMinutes(5)
};
});
Com o hybrid caching, você define uma expiração geral e uma expiração local para o cache na memória do servidor.
Response caching
Para habilitar o response caching, você precisa adicionar o middleware ResponseCachingMiddleware
à sua aplicação.
builder.Services.AddResponseCaching();
app.UseResponseCaching();
O response caching utiliza os headers HTTP Cache-Control
para determinar se a resposta pode ser armazenada em cache pelo cliente ou por um proxy.
Output caching
O output caching oferece maior flexibilidade, permitindo configurar o cache no servidor e invalidar entradas programaticamente. É possível utilizar o output caching com in-memory, distributed ou hybrid caching.
app.MapPost("/author/getauthors", ([FromServices] IAuthorRepository authorRepository) =>
{
return authorRepository.GetAll();
}).CacheOutput(x => x.Expire(TimeSpan.FromSeconds(30)));
Neste exemplo, a resposta do endpoint é armazenada em cache por 30 segundos.
Boas Práticas de Caching
Para tirar o máximo proveito do caching em suas aplicações ASP.NET Core, siga estas dicas:
- Escolha a estratégia de caching adequada para o seu caso de uso.
- Defina políticas de expiração apropriadas.
- Não armazene dados sensíveis em cache.
- Utilize a invalidação de cache quando necessário.
- Monitore as taxas de acerto e erro do cache para otimizar sua estratégia.
Conclusão
Implementar caching em Minimal APIs do ASP.NET Core é uma excelente forma de otimizar a performance e a escalabilidade das suas aplicações. Ao entender os diferentes tipos de caching disponíveis e seguir as boas práticas, você pode garantir que seus usuários tenham uma experiência rápida e eficiente. Lembre-se de que a escolha da estratégia de caching mais adequada depende das necessidades específicas da sua aplicação, e que o monitoramento constante do cache é fundamental para garantir seu bom funcionamento.