Non c’è niente di più frustrante che fissare lo schermo per 10 o 20 secondi, aspettando che una pagina si carichi. Sapevi che un tempo di risposta compreso tra 200 millisecondi e 1 secondo è considerato accettabile, poiché probabilmente non noterai il ritardo? Tuttavia, superata questa soglia, l’impazienza e la frustrazione iniziano a farsi sentire.

È qui che entra in gioco la gestione efficace della cache, un aspetto cruciale per le prestazioni delle applicazioni web moderne. Se sei uno sviluppatore ASP.NET Core, potresti essere sempre alla ricerca di soluzioni di caching potenti, flessibili e facili da usare. Ed è proprio qui che, a mio parere, FusionCache si distingue.

Cos’è FusionCache

FusionCache è una libreria di caching open source per .NET facile da usare. Con poche righe di codice, puoi integrare un sistema di cache avanzato e iniziare a trarre vantaggi. Nonostante la sua semplicità, FusionCache offre un’ampia gamma di funzionalità avanzate per soddisfare anche i casi d’uso più complessi. Con il supporto per chiavi composite, scadenza della cache, caching distribuito e molto altro, dandoti un controllo completo sulla tua strategia di caching.

Implementazione

Per prima cosa, crea una nuova applicazione ASP.NET Core Web API è successivamente installa la libreria di FusionCache.

dotnet add package ZiggyCreatures.FusionCache 1.4.1
Soluzione FusionCache

Configurazione FusionCache

Program.cs

services.AddFusionCache().TryWithAutoSetup();

Come puoi notare, la configurazione è così semplice che basta una sola riga di codice per impostare FusionCache. Se hai bisogno di una configurazione più complessa, ti consiglio di consultare la documentazione ufficiale.

Come utilizzare FusionCache ?

Per utilizzare FusionCache, segui questi passaggi per configurare correttamente il tuo progetto:

Configurazione del supporto per i controller

A partire da .NET 8, i template predefiniti non aggiungono più il supporto per registrare i controller in modo automatico, poiché il modello di sviluppo è stato semplificato tramite l’introduzione delle Minimal APIs. Con questo approccio, invece di usare i controller tradizionali, si possono definire direttamente le route usando MapGet(), MapPost(), ecc., eliminando la necessità di un controller separato.

Tuttavia, personalmente preferisco ancora utilizzare i controller, poiché li trovo più chiari e organizzati, specialmente per progetti di dimensioni medio-grandi. Se anche tu preferisci mantenere il vecchio approccio con i controller, ecco come puoi configurare correttamente il progetto in .NET 8.

Program.cs

// Aggiunge il supporto per i controller API
builder.Services.AddControllers();

// Configura il routing per i controller
app.MapControllers();

Creare un controller API

Per testare il corretto funzionamento di FusionCache, dovrai creare un controller API. All’interno di questo controller, implementerai tre endpoint:

  • SyncCache: Sincronizza i dati nella cache. Effettua una chiamata HTTP per ottenere i dati aggiornati e li memorizza nella cache utilizzando la chiave CACHE_KEY.
  • CacheData: Recupera i dati dalla cache utilizzando la chiave CACHE_KEY. Se i dati non sono presenti nella cache, viene restituito lo status code 204 (No Content).
  • NoCacheData: Recupera i dati direttamente dall’API utilizzata senza passare dalla cache.

Anche se tutte e tre le API non sono strettamente necessarie per il progetto, rappresentano un buon esempio per comprendere le differenze tra i vari approcci nell’utilizzo della cache. Potrai così testare in modo pratico come FusionCache gestisce la memorizzazione e il recupero dei dati, sia utilizzando la cache che bypassandola.

Controllers/FusionCacheController.cs

using FusionCache.NET.Properties.Models;
using Microsoft.AspNetCore.Mvc;
using ZiggyCreatures.Caching.Fusion;

namespace FusionCache.NET.Controllers;

[ApiController]
[Route("[controller]/[action]")]
public class FusionCacheController(IFusionCache fusionCache, IConfiguration configuration) : ControllerBase
{
    private const string TODO_PATH = "/todos";  // Percorso per ottenere i "To-Do" dall'API esterna
    private const string CACHE_KEY = "cache_todos";  // Chiave di cache per memorizzare i dati dei "To-Do"
    private const string URI_KEY = "TCode";  // Chiave di configurazione per l'URL dell'API esterna
    
    // Inizializzazione di un oggetto HttpClient per effettuare chiamate HTTP
    private readonly HttpClient _httpClient = new HttpClient
    {
        // Imposta l'URL di base dell'API esterna, ottenuto dalla configurazione
        BaseAddress = new Uri(configuration.GetValue<string>(URI_KEY) ?? string.Empty)
    };
    
    // Metodo per sincronizzare i dati nella cache (esegue una chiamata HTTP e aggiorna la cache)
    [HttpGet]
    public async Task<IActionResult> SyncCache(CancellationToken cancellationToken)
    {
        var todosResponseMessage = await _httpClient.GetAsync(TODO_PATH, cancellationToken);

        var response = await todosResponseMessage.Content.ReadFromJsonAsync<IList<ToDoModel>>(cancellationToken);
        
        return Ok(await fusionCache.GetOrSetAsync(CACHE_KEY, response, token: cancellationToken));
    }
    
    // Metodo per recuperare i dati dalla cache, se disponibili
    [HttpGet]
    public async Task<IActionResult> CacheData(CancellationToken cancellationToken)
    {
        return Ok(await fusionCache.GetOrDefaultAsync<IList<ToDoModel>>(CACHE_KEY, token: cancellationToken));
    }
    
    // Metodo per recuperare i dati direttamente dall'API esterna, senza utilizzare la cache
    [HttpGet]
    public async Task<IActionResult> NoCacheData(CancellationToken cancellationToken)
    {
        var todosResponseMessage = await _httpClient.GetAsync(TODO_PATH, cancellationToken);

        return Ok(await todosResponseMessage.Content.ReadFromJsonAsync<IList<ToDoModel>>(cancellationToken));
    }
}

Definire la classe ToDoModel

Per deserializzare i dati restituiti dall’API esterna, è necessario creare una classe che rappresenti la struttura dell’oggetto restituito.

Models/ToDoModel.cs

public class ToDoModel
{
    public required int UserId { get; set; }
    public required int Id { get; set; }
    public required string Title { get; set; }
    public required bool Completed { get; set; }
}

Aggiungere la chiave API nel appsettings.json

Per configurare correttamente l’API esterna da cui recuperare i dati, è necessario aggiungere l’URL nel file appsettings.json. Apri il file appsettings.json e aggiungi la seguente chiave:

{
  "TCode": "https://jsonplaceholder.typicode.com"
}

Testare FusionCache

Per testare le API create nel controller FusionCacheController, puoi utilizzare un file HTTP (ad esempio, in formato .http o .rest) che contenga le richieste verso il server locale. Ecco un esempio di file HTTP per testare le diverse API:

@FusionCacheNET_HostAddress = http://localhost:5004

### Sincronizzare la cache
GET {{FusionCacheNET_HostAddress}}/FusionCache/SyncCache/
Accept: application/json

###

### Utilizzare i dati dalla cache
GET {{FusionCacheNET_HostAddress}}/FusionCache/CacheData
Accept: application/json

###

### Recuperare i dati senza cache
GET {{FusionCacheNET_HostAddress}}/FusionCache/NoCacheData/
Accept: application/json

Alternativamente, se hai configurato Swagger UI nel tuo progetto, puoi testare le API direttamente attraverso l’interfaccia grafica fornita da Swagger. Basta navigare all’endpoint /swagger (ad esempio, http://localhost:5004/swagger) e interagire con le API tramite la UI.

Conclusione

Se hai seguito fin qui, avrai sicuramente creato la tua applicazione per testare FusionCache e sperimentato le sue potenzialità. Le possibilità sono infinite: personalizza la tua configurazione, esplora funzionalità avanzate e costruisci soluzioni scalabili.

Grazie per aver letto questo articolo! Se vuoi approfondire, il codice sorgente è disponibile su GitHub: FusioCache.NET. Cosa ne pensi di questa soluzione? Fammi sapere nei commenti!

Tagged in:

,