День 1521. #ЗаметкиНаПолях
Кэширование Вывода в ASP.NET Core. Продолжение
Начало
Ключи кэша
По умолчанию ключом кэша для конечной точки является полный URL. Если добавить параметры строки запроса, ключ также будет включать их значения и отдельно кэшировать элементы. Если мы хотим иметь больший контроль над тем, как создаётся ключ кэша, можно явно это указать.
1. Вариация по запросу
Изменим политику CacheTenSec:
opt.AddPolicy("CacheTenSec", c =>
c.Expire(TimeSpan.FromSeconds(10))
.SetVaryByQuery("par1"));
Здесь мы указываем, что хотим менять ключ кэша для параметра строки запроса par1. Теперь для каждого уникального значения par1 будет возвращаться свой ответ, кэшированный на 10 секунд. Однако другие параметры запроса на это влиять не будут. Например: www.site.com и www.site.com?par2=123 вернут один и тот же кэшированный ответ. Это может быть полезно, если мы хотим чётко указать, как результаты варьируются в зависимости от параметров.
2. Вариация по заголовку
opt.AddPolicy("CacheTenSec", c =>
c.Expire(TimeSpan.FromSeconds(10))
.SetVaryByQuery("par1")
.SetVaryByHeader("X-Client-Id"));
Здесь мы указываем, что хотим, чтобы кэш варьировался в зависимости от значения заголовка X-Client-Id (браузер клиента). Наиболее распространённый вариант использования вариации по заголовку — во время согласования содержимого - вариация по заголовку Accept. Например, можно по-разному кэшировать ответы JSON и XML из-за разных затрат по обработке этих запросов на сервере.
3. Существует также VaryByValue, более сложная конфигурация, которая позволяет изменять ключ по вычисляемому на сервере значению.
Повторная проверка кэша
До сих пор мы возвращали полное тело кэшированного ответа, даже если оно было идентично предыдущему ответу. Но можно просто проинструктировать клиента, что ответ тот же.
Добавим ещё одну конечную точку, используя минимальные API в Program.cs:
app.MapGet("/etag", async (context) =>
{
var etag = $"\"{Guid.NewGuid():n}\"";
context.Response.Headers.ETag = etag;
await context.Response.WriteAsync("hello");
}).CacheOutput();
Здесь мы устанавливаем специальный заголовок ответа, называемый ETag, со значением GUID. Если мы сделаем запрос к URL /etag в Postman, мы увидим в ответе:
- заголовок ETag,
- код ответа 200 (ОК),
- тело ответа «hello».
Добавим в запрос специальный заголовок If-None-Match со значением только что полученного ETag (увеличьте время кэширования в настройках, чтобы успеть это сделать). Теперь мы получим ответ 304 и пустое тело ответа. Это связано с тем, что с помощью заголовка If-None-Match клиент проинструктировал сервер, что у него уже есть копия ответа с таким значением ETag, поэтому, если оно не изменилось, не нужно повторно отправлять содержимое, просто нужно сообщить об этом факте с кодом ответа 304. Это очень мощный способ уменьшить объём обработки как на клиенте, так и на сервере.
Окончание следует…
Источник: https://code-maze.com/aspnet-core-output-caching/