diff --git a/Media.JoshHeaps.Net/Api/BlogApi.cs b/Media.JoshHeaps.Net/Api/BlogApi.cs index f40ae8a..55c203f 100644 --- a/Media.JoshHeaps.Net/Api/BlogApi.cs +++ b/Media.JoshHeaps.Net/Api/BlogApi.cs @@ -6,7 +6,7 @@ namespace Media.JoshHeaps.Net.Api; [ApiController] [Route("api/blog")] -public class BlogApi(BlogService blogService, DbExecutor dbExecutor) : ControllerBase +public class BlogApi(BlogService blogService, DbExecutor dbExecutor, IHttpClientFactory httpClientFactory, IConfiguration configuration, ILogger logger) : ControllerBase { [HttpGet("posts")] public async Task GetPosts() @@ -65,6 +65,7 @@ public class BlogApi(BlogService blogService, DbExecutor dbExecutor) : Controlle if (post is null) return StatusCode(500, new { error = "Failed to create post" }); + _ = InvalidateFrontendCacheAsync(); return Ok(MapToAdminDto(post)); } @@ -91,6 +92,7 @@ public class BlogApi(BlogService blogService, DbExecutor dbExecutor) : Controlle if (post is null) return NotFound(new { error = "Post not found" }); + _ = InvalidateFrontendCacheAsync(); return Ok(MapToAdminDto(post)); } @@ -104,6 +106,7 @@ public class BlogApi(BlogService blogService, DbExecutor dbExecutor) : Controlle var deleted = await blogService.DeletePostAsync(id); if (!deleted) return NotFound(new { error = "Post not found" }); + _ = InvalidateFrontendCacheAsync(); return Ok(new { success = true }); } @@ -158,6 +161,26 @@ public class BlogApi(BlogService blogService, DbExecutor dbExecutor) : Controlle post.UpdatedAt }; + private async Task InvalidateFrontendCacheAsync() + { + try + { + var url = configuration["BlogCache:InvalidateUrl"]; + var key = configuration["BlogCache:InvalidateKey"]; + if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(key)) return; + + var client = httpClientFactory.CreateClient(); + client.Timeout = TimeSpan.FromSeconds(5); + var request = new HttpRequestMessage(HttpMethod.Post, url); + request.Headers.Add("X-Invalidate-Key", key); + await client.SendAsync(request); + } + catch (Exception ex) + { + logger.LogWarning(ex, "Failed to invalidate frontend blog cache"); + } + } + private async Task IsAdmin(long userId) { return await dbExecutor.ExecuteAsync( diff --git a/Media.JoshHeaps.Net/Program.cs b/Media.JoshHeaps.Net/Program.cs index ce24eb8..dab4ad8 100644 --- a/Media.JoshHeaps.Net/Program.cs +++ b/Media.JoshHeaps.Net/Program.cs @@ -20,6 +20,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddSingleton(); builder.Services.AddScoped(); +builder.Services.AddHttpClient(); // Add session support builder.Services.AddDistributedMemoryCache(); diff --git a/Media.JoshHeaps.Net/appsettings.json b/Media.JoshHeaps.Net/appsettings.json index b05998d..852491e 100644 --- a/Media.JoshHeaps.Net/appsettings.json +++ b/Media.JoshHeaps.Net/appsettings.json @@ -20,6 +20,10 @@ "FromName": "Media App", "EnableSsl": "true" }, + "BlogCache": { + "InvalidateUrl": "https://joshheaps.net/api/blog/invalidate", + "InvalidateKey": "CHANGE_ME" + }, "FileUpload": { "MaxFileSizeMB": 10, "AllowedImageTypes": ["image/jpeg", "image/png", "image/gif", "image/webp"],