diff --git a/src/Portfolio.Api/Controller/AboutController.cs b/src/Portfolio.Api/Controller/AboutController.cs index 8a8f2b4..886a595 100644 --- a/src/Portfolio.Api/Controller/AboutController.cs +++ b/src/Portfolio.Api/Controller/AboutController.cs @@ -1,9 +1,10 @@ using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.OutputCaching; using Portfolio.Shared.Services; namespace Portfolio.Api.Controller; -[ApiController, Route("api/about")] +[ApiController, Route("api/about"), OutputCache(Tags = [DatabaseContext.CacheKey])] public class AboutController(IAboutRepository repository) : ControllerBase { [HttpGet] diff --git a/src/Portfolio.Api/Controller/ProjectController.cs b/src/Portfolio.Api/Controller/ProjectController.cs index 139228e..2a74271 100644 --- a/src/Portfolio.Api/Controller/ProjectController.cs +++ b/src/Portfolio.Api/Controller/ProjectController.cs @@ -1,9 +1,10 @@ using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.OutputCaching; using Portfolio.Shared.Services; namespace Portfolio.Api.Controller; -[ApiController, Route("api/projects")] +[ApiController, Route("api/projects"), OutputCache(Tags = [DatabaseContext.CacheKey])] public class ProjectController(IProjectRepository repository) : ControllerBase { [HttpGet] diff --git a/src/Portfolio.Api/Controller/TechnologyController.cs b/src/Portfolio.Api/Controller/TechnologyController.cs index 40de333..33a997f 100644 --- a/src/Portfolio.Api/Controller/TechnologyController.cs +++ b/src/Portfolio.Api/Controller/TechnologyController.cs @@ -1,9 +1,10 @@ using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.OutputCaching; using Portfolio.Shared.Services; namespace Portfolio.Api.Controller; -[ApiController, Route("api/technologies")] +[ApiController, Route("api/technologies"), OutputCache(Tags = [DatabaseContext.CacheKey])] public class TechnologyController(ITechnologyRepository repository) : ControllerBase { [HttpGet] diff --git a/src/Portfolio.Api/Controller/TimelineController.cs b/src/Portfolio.Api/Controller/TimelineController.cs index b2a6597..c78d675 100644 --- a/src/Portfolio.Api/Controller/TimelineController.cs +++ b/src/Portfolio.Api/Controller/TimelineController.cs @@ -1,10 +1,11 @@ using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.OutputCaching; using Portfolio.Shared.Models; using Portfolio.Shared.Services; namespace Portfolio.Api.Controller; -[ApiController, Route("api/timeline")] +[ApiController, Route("api/timeline"), OutputCache(Tags = [DatabaseContext.CacheKey])] public class TimelineController(ITimelineRepository repository) : ControllerBase { [HttpGet("{type}")] diff --git a/src/Portfolio.Api/DatabaseContext.cs b/src/Portfolio.Api/DatabaseContext.cs index 5a5ccc2..a5aa0cc 100644 --- a/src/Portfolio.Api/DatabaseContext.cs +++ b/src/Portfolio.Api/DatabaseContext.cs @@ -1,9 +1,12 @@ -using Microsoft.EntityFrameworkCore; +using Microsoft.AspNetCore.OutputCaching; +using Microsoft.EntityFrameworkCore; using Portfolio.Shared.Models; namespace Portfolio.Api; -public class DatabaseContext(DbContextOptions options) : DbContext(options) { +public class DatabaseContext(DbContextOptions options, IOutputCacheStore cacheStore) : DbContext(options) { + + public const string CacheKey = "portfolio-data"; public DbSet Projects { get; set; } @@ -19,5 +22,9 @@ public class DatabaseContext(DbContextOptions options) : DbCont .WithMany() .UsingEntity("LanguageProject"); } - + + public override async Task SaveChangesAsync(CancellationToken cancellationToken = new()) { + await cacheStore.EvictByTagAsync(CacheKey, cancellationToken); + return await base.SaveChangesAsync(cancellationToken); + } } \ No newline at end of file diff --git a/src/Portfolio.Api/Portfolio.Api.csproj b/src/Portfolio.Api/Portfolio.Api.csproj index f7751ce..8cdda73 100644 --- a/src/Portfolio.Api/Portfolio.Api.csproj +++ b/src/Portfolio.Api/Portfolio.Api.csproj @@ -9,6 +9,7 @@ + diff --git a/src/Portfolio.Api/Program.cs b/src/Portfolio.Api/Program.cs index 7030e00..528c0e1 100644 --- a/src/Portfolio.Api/Program.cs +++ b/src/Portfolio.Api/Program.cs @@ -1,6 +1,5 @@ using HopFrame.Core.Config; using HopFrame.Web; -using Microsoft.EntityFrameworkCore; using Portfolio.Api; using Portfolio.Api.Services; using Portfolio.Shared.Models; @@ -23,6 +22,11 @@ builder.Services.AddScoped(); builder.Services.AddControllers(); +builder.AddRedisOutputCache("cache"); +builder.Services.AddOutputCache(options => { + options.DefaultExpirationTimeSpan = TimeSpan.FromDays(30); +}); + builder.Services.AddHopFrame(options => { options.DisplayUserInfo(false); options.AddDbContext(context => { @@ -94,6 +98,8 @@ await using (var scope = app.Services.CreateAsyncScope()) { app.MapDefaultEndpoints(); +app.UseOutputCache(); + app.MapControllers(); app.UseAntiforgery(); diff --git a/src/Portfolio.Host/Portfolio.Host.csproj b/src/Portfolio.Host/Portfolio.Host.csproj index 083deb5..8868389 100644 --- a/src/Portfolio.Host/Portfolio.Host.csproj +++ b/src/Portfolio.Host/Portfolio.Host.csproj @@ -14,6 +14,7 @@ + diff --git a/src/Portfolio.Host/Program.cs b/src/Portfolio.Host/Program.cs index ae405b9..5223bad 100644 --- a/src/Portfolio.Host/Program.cs +++ b/src/Portfolio.Host/Program.cs @@ -5,9 +5,13 @@ var postgres = builder.AddPostgres("postgres") var db = postgres.AddDatabase("data"); +var cache = builder.AddRedis("cache"); + var api = builder.AddProject("api") .WithReference(db) - .WaitFor(db); + .WaitFor(db) + .WithReference(cache) + .WaitFor(cache); builder.AddProject("web") .WithReference(api)