I'm trying to setup output caching using Entity GraphQl, but can't get it to work. It's a net8.0 project with EntityGraphQL.AspNet 5.1.1.
Here's my reduced Program.cs
using EntityGraphQL.AspNet;
using MedicalData.DataAccess;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddOutputCache();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddMedicalDataDataAccess(builder.Configuration.GetSection("MedicalDataDataAccess").Bind);
builder.Services.AddGraphQLSchema<MedicalDataDbContext>();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseOutputCache();
app.MapGraphQL<MedicalDataDbContext>(
configureEndpoint: endpointConventionBuilder =>
endpointConventionBuilder.CacheOutput(outputCachePolicyBuilder =>
{
outputCachePolicyBuilder.VaryByValue(context =>
{
context.Request.EnableBuffering();
using var bodyReader = new StreamReader(context.Request.Body, leaveOpen: true);
var bodyContent = bodyReader.ReadToEndAsync()
.Result
.Replace(" ", "");
// Reset the stream position to enable subsequent reads
context.Request.Body.Position = 0;
Console.WriteLine($"VaryByValue: {bodyContent}");
return new KeyValuePair<string, string>("graphQl-requestBody", bodyContent);
});
outputCachePolicyBuilder.Expire(TimeSpan.FromHours(6));
}));
app.MapGraphQLAltair();
app.MapControllers();
app.Run();
When executing the same graphql query multiple times, it is never being retrieved from the cache. The vary by value function is being executed each time, then the EF query:
VaryByValue: {"query":"{\narticle(id:3){\nupdatedOn\ndescription{\ncurrent\n}\n}\n}","variables":{},"operationName":null}
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[@__Value_id_Value_0='?' (DbType = Int64)], CommandType='Text', CommandTimeout='30']
SELECT ...
VaryByValue: {"query":"{\narticle(id:3){\nupdatedOn\ndescription{\ncurrent\n}\n}\n}","variables":{},"operationName":null}
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[@__Value_id_Value_0='?' (DbType = Int64)], CommandType='Text', CommandTimeout='30']
SELECT ...
I've added a log entry in a controller endpoint marked with [OutputCache(Duration = 60 * 60)]. If it is being called multiple times, only the first call enters, the subsequent ones come from the cache:
GetPaged ArticleResultDtos
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT COUNT(*)
FROM [Articles] AS [a]
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (3ms) [Parameters=[@__p_0='?' (DbType = Int32), @__p_1='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']
SELECT ...
When using Redis, instead of the in memory cache for output caching, there is no entry written for graphql, for the controller call, there is one.
What am I missing to make the GraphQl output cache work?