Quando un sito web sfrutta l'output cache, come abbiamo visto finora in ASP.NET Core 7, il server evita di processare la richiesta e fornisce immediatamente la stessa risposta di un'invocazione analoga avvenuta in precedenza.
Si tratta di una grande ottimizzazione per l'uso delle risorse del server, perché la risposta richiede pochissima CPU, ma c'è comunque un transito di dati sulla rete, che può avere costi a livelli di banda e anche di performance.
Una soluzione standard a questo problema è l'uso degli ETag (Entity Tag: https://www.w3.org/2005/MWI/BPWG/techs/CachingWithETag.html), ossia degli identificativi che vengono associati alla risposta del server. Cerchiamo di capire come sfruttarli in ASP.NET Core 7.
Il primo passo è quello di aggiungere l'Etag alla risposta che generiamo:
[HttpGet("demo")] public IActionResult Cached(string name) { this.HttpContext.Response.Headers.ETag = $"\"{Guid.NewGuid():n}\""; return this.Ok($"Hello, {name}, time is {DateTime.Now.ToLongTimeString()} and this is cached"); }
Il tag, come possiamo vedere, è semplicemente un Guid che generiamo randomicamente, e che verrà catturato dal middleware di OutputCache e memorizzato unitamente alla risposta.
A questo punto, immaginiamo di avere un client, per esempio un sito Blazor, in cui invochiamo l'endpoint in alto:
<button class="btn btn-primary" @onclick="FetchDataAsync">Click me</button> <p>@apiResponse</p> @code { private string apiResponse = "No response"; private async Task FetchDataAsync() { apiResponse = await Http.GetStringAsync( "https://localhost:7088/api/cache/demo?name=Marco"); } }
Come possiamo notare, si tratta di una normalissima richiesta tramite HttpClient, senza alcuna logica di cache.
Quando il browser esegue la richiesta per la prima volta, riceve l'ETag che verrà memorizzato nella sua local cache, unitamente al contenuto della risposta.
HTTP/2 200 OK content-type: text/plain; charset=utf-8 date: Sun, 05 Mar 2023 11:59:40 GMT server: Kestrel access-control-allow-origin: * etag: "9360fbd21d0d4ec9919a0a0dcd2ba0b9"
A una successiva richiesta, invierà lo stesso ETag in un header If-None-Match, come nel trace in basso:
GET /api/cache/demo?name=Marco HTTP/2 Host: localhost:7088 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0 Accept: */* Accept-Language: en-GB,en;q=0.5 ... If-None-Match: "9360fbd21d0d4ec9919a0a0dcd2ba0b9"
A questo punto, entra in gioco nuovamente il middleware di OutputCache in ASP.NET Core 7, che confronta questo header con l'ETag in cache, rispondendo con uno status code 304 Not Modified in caso di match, senza inviare alcun contenuto.
HTTP/2 304 Not Modified date: Sun, 05 Mar 2023 11:59:40 GMT server: Kestrel access-control-allow-origin: * etag: "9360fbd21d0d4ec9919a0a0dcd2ba0b9" X-Firefox-Spdy: h2
Il risultato serve a segnalare al browser che la sua cache locale è ancora valida, e può essere utilizzata come valore della risposta. La chiamata pertanto avrà una durata pressoché istantanea, come possiamo notare dall'immagine in basso.
Allo scadere della cache sul server, invece, il middleware di OutputCache non riconoscerà più l'ETag inviato dal browser, e risponderà con un 200 OK inviando anche il contenuto della risposta.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Filtering sulle colonne in una QuickGrid di Blazor
Gestire eccezioni nei plugin di Semantic Kernel in ASP.NET Core Web API
Evitare (o ridurre) il repo-jacking sulle GitHub Actions
Ordine e importanza per @layer in CSS
Supportare il sorting di dati tabellari in Blazor con QuickGrid
Aggiornare a .NET 9 su Azure App Service
Triggerare una pipeline su un altro repository di Azure DevOps
Utilizzare il trigger SQL con le Azure Function
Eseguire query per recuperare il padre di un record che sfrutta il tipo HierarchyID in Entity Framework
Evitare il flickering dei componenti nel prerender di Blazor 8
Utilizzare Model as a Service su Microsoft Azure
I più letti di oggi
- Simulare Azure Cosmos DB in locale con Docker
- Utilizzare il metodo Index di LINQ per scorrere una lista sapendo anche l'indice dell'elemento
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!
- .NET Conference Italia 2024 - Milano
- .NET Conference Italia 2023 - Milano e Online