diff --git a/services/Directory/FilterLists.Directory.Api/Controllers/BaseController.cs b/services/Directory/FilterLists.Directory.Api/Controllers/BaseController.cs
new file mode 100644
index 000000000..12916ecbf
--- /dev/null
+++ b/services/Directory/FilterLists.Directory.Api/Controllers/BaseController.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Runtime.CompilerServices;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Caching.Memory;
+
+namespace FilterLists.Directory.Api.Controllers
+{
+ public abstract class BaseController : ControllerBase
+ {
+ private readonly IMemoryCache _cache;
+
+ protected BaseController(IMemoryCache cache)
+ {
+ _cache = cache;
+ }
+
+ /// https://stackoverflow.com/a/52506210/2343739
+ protected async Task CacheGetOrCreateAsync(
+ Func> actionAsync,
+ int? keySuffix = default,
+ TimeSpan? absoluteExpirationRelativeToNow = default,
+ [CallerMemberName] string key = default!)
+ {
+ var cacheKey = $"{GetType().Name}_{key}{(keySuffix is null ? string.Empty : $"_{keySuffix}")}";
+ var result = await _cache.GetOrCreateAsync(cacheKey, entry =>
+ {
+ entry.AbsoluteExpirationRelativeToNow = absoluteExpirationRelativeToNow;
+ return actionAsync();
+ });
+ return result is null ? NotFound() : (IActionResult)Ok(result);
+ }
+ }
+}
\ No newline at end of file
diff --git a/services/Directory/FilterLists.Directory.Api/Controllers/LanguagesController.cs b/services/Directory/FilterLists.Directory.Api/Controllers/LanguagesController.cs
index 9ab3b196c..ce60862f4 100644
--- a/services/Directory/FilterLists.Directory.Api/Controllers/LanguagesController.cs
+++ b/services/Directory/FilterLists.Directory.Api/Controllers/LanguagesController.cs
@@ -5,25 +5,27 @@
using FilterLists.Directory.Application.Queries;
using MediatR;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Caching.Memory;
namespace FilterLists.Directory.Api.Controllers
{
[ApiController]
[Route("[controller]")]
- public class LanguagesController : ControllerBase
+ public class LanguagesController : BaseController
{
private readonly IMediator _mediator;
- public LanguagesController(IMediator mediator)
+ public LanguagesController(IMemoryCache cache, IMediator mediator) : base(cache)
{
_mediator = mediator;
}
[HttpGet]
[ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)]
+ [ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task Get(CancellationToken cancellationToken)
{
- return Ok(await _mediator.Send(new GetLanguages.Query(), cancellationToken));
+ return await CacheGetOrCreateAsync(() => _mediator.Send(new GetLanguages.Query(), cancellationToken));
}
}
}
\ No newline at end of file
diff --git a/services/Directory/FilterLists.Directory.Api/Controllers/LicensesController.cs b/services/Directory/FilterLists.Directory.Api/Controllers/LicensesController.cs
index b7ed3373f..afbe7768f 100644
--- a/services/Directory/FilterLists.Directory.Api/Controllers/LicensesController.cs
+++ b/services/Directory/FilterLists.Directory.Api/Controllers/LicensesController.cs
@@ -5,25 +5,27 @@
using FilterLists.Directory.Application.Queries;
using MediatR;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Caching.Memory;
namespace FilterLists.Directory.Api.Controllers
{
[ApiController]
[Route("[controller]")]
- public class LicensesController : ControllerBase
+ public class LicensesController : BaseController
{
private readonly IMediator _mediator;
- public LicensesController(IMediator mediator)
+ public LicensesController(IMemoryCache cache, IMediator mediator) : base(cache)
{
_mediator = mediator;
}
[HttpGet]
[ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)]
+ [ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task Get(CancellationToken cancellationToken)
{
- return Ok(await _mediator.Send(new GetLicenses.Query(), cancellationToken));
+ return await CacheGetOrCreateAsync(() => _mediator.Send(new GetLicenses.Query(), cancellationToken));
}
}
}
\ No newline at end of file
diff --git a/services/Directory/FilterLists.Directory.Api/Controllers/ListsController.cs b/services/Directory/FilterLists.Directory.Api/Controllers/ListsController.cs
index 6ea329d3f..344bbb7c2 100644
--- a/services/Directory/FilterLists.Directory.Api/Controllers/ListsController.cs
+++ b/services/Directory/FilterLists.Directory.Api/Controllers/ListsController.cs
@@ -6,32 +6,35 @@
using FilterLists.SharedKernel.Apis.Contracts.Directory;
using MediatR;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Caching.Memory;
namespace FilterLists.Directory.Api.Controllers
{
[ApiController]
[Route("[controller]")]
- public class ListsController : ControllerBase
+ public class ListsController : BaseController
{
private readonly IMediator _mediator;
- public ListsController(IMediator mediator)
+ public ListsController(IMemoryCache cache, IMediator mediator) : base(cache)
{
_mediator = mediator;
}
[HttpGet]
[ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)]
+ [ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task Get(CancellationToken cancellationToken)
{
- return Ok(await _mediator.Send(new GetLists.Query(), cancellationToken));
+ return await CacheGetOrCreateAsync(() => _mediator.Send(new GetLists.Query(), cancellationToken));
}
[HttpGet("{id}")]
[ProducesResponseType(typeof(ListDetailsVm), (int)HttpStatusCode.OK)]
+ [ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task GetDetails(int id, CancellationToken cancellationToken)
{
- return Ok(await _mediator.Send(new GetListDetails.Query(id), cancellationToken));
+ return await CacheGetOrCreateAsync(() => _mediator.Send(new GetListDetails.Query(id), cancellationToken), id);
}
}
}
\ No newline at end of file
diff --git a/services/Directory/FilterLists.Directory.Api/Controllers/MaintainersController.cs b/services/Directory/FilterLists.Directory.Api/Controllers/MaintainersController.cs
index 2e259a2f2..5e1bd3845 100644
--- a/services/Directory/FilterLists.Directory.Api/Controllers/MaintainersController.cs
+++ b/services/Directory/FilterLists.Directory.Api/Controllers/MaintainersController.cs
@@ -5,25 +5,27 @@
using FilterLists.Directory.Application.Queries;
using MediatR;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Caching.Memory;
namespace FilterLists.Directory.Api.Controllers
{
[ApiController]
[Route("[controller]")]
- public class MaintainersController : ControllerBase
+ public class MaintainersController : BaseController
{
private readonly IMediator _mediator;
- public MaintainersController(IMediator mediator)
+ public MaintainersController(IMemoryCache cache, IMediator mediator) : base(cache)
{
_mediator = mediator;
}
[HttpGet]
[ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)]
+ [ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task Get(CancellationToken cancellationToken)
{
- return Ok(await _mediator.Send(new GetMaintainers.Query(), cancellationToken));
+ return await CacheGetOrCreateAsync(() => _mediator.Send(new GetMaintainers.Query(), cancellationToken));
}
}
}
\ No newline at end of file
diff --git a/services/Directory/FilterLists.Directory.Api/Controllers/SoftwareController.cs b/services/Directory/FilterLists.Directory.Api/Controllers/SoftwareController.cs
index fb08bc5ef..896651fc8 100644
--- a/services/Directory/FilterLists.Directory.Api/Controllers/SoftwareController.cs
+++ b/services/Directory/FilterLists.Directory.Api/Controllers/SoftwareController.cs
@@ -5,25 +5,27 @@
using FilterLists.Directory.Application.Queries;
using MediatR;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Caching.Memory;
namespace FilterLists.Directory.Api.Controllers
{
[ApiController]
[Route("[controller]")]
- public class SoftwareController : ControllerBase
+ public class SoftwareController : BaseController
{
private readonly IMediator _mediator;
- public SoftwareController(IMediator mediator)
+ public SoftwareController(IMemoryCache cache, IMediator mediator) : base(cache)
{
_mediator = mediator;
}
[HttpGet]
[ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)]
+ [ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task Get(CancellationToken cancellationToken)
{
- return Ok(await _mediator.Send(new GetSoftware.Query(), cancellationToken));
+ return await CacheGetOrCreateAsync(() => _mediator.Send(new GetSoftware.Query(), cancellationToken));
}
}
}
\ No newline at end of file
diff --git a/services/Directory/FilterLists.Directory.Api/Controllers/SyntaxesController.cs b/services/Directory/FilterLists.Directory.Api/Controllers/SyntaxesController.cs
index e6e869a7e..a4c8809d2 100644
--- a/services/Directory/FilterLists.Directory.Api/Controllers/SyntaxesController.cs
+++ b/services/Directory/FilterLists.Directory.Api/Controllers/SyntaxesController.cs
@@ -5,25 +5,27 @@
using FilterLists.Directory.Application.Queries;
using MediatR;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Caching.Memory;
namespace FilterLists.Directory.Api.Controllers
{
[ApiController]
[Route("[controller]")]
- public class SyntaxesController : ControllerBase
+ public class SyntaxesController : BaseController
{
private readonly IMediator _mediator;
- public SyntaxesController(IMediator mediator)
+ public SyntaxesController(IMemoryCache cache, IMediator mediator) : base(cache)
{
_mediator = mediator;
}
[HttpGet]
[ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)]
+ [ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task Get(CancellationToken cancellationToken)
{
- return Ok(await _mediator.Send(new GetSyntaxes.Query(), cancellationToken));
+ return await CacheGetOrCreateAsync(() => _mediator.Send(new GetSyntaxes.Query(), cancellationToken));
}
}
}
\ No newline at end of file
diff --git a/services/Directory/FilterLists.Directory.Api/Controllers/TagsController.cs b/services/Directory/FilterLists.Directory.Api/Controllers/TagsController.cs
index ecc660cd2..e91267a87 100644
--- a/services/Directory/FilterLists.Directory.Api/Controllers/TagsController.cs
+++ b/services/Directory/FilterLists.Directory.Api/Controllers/TagsController.cs
@@ -5,25 +5,27 @@
using FilterLists.Directory.Application.Queries;
using MediatR;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Caching.Memory;
namespace FilterLists.Directory.Api.Controllers
{
[ApiController]
[Route("[controller]")]
- public class TagsController : ControllerBase
+ public class TagsController : BaseController
{
private readonly IMediator _mediator;
- public TagsController(IMediator mediator)
+ public TagsController(IMemoryCache cache, IMediator mediator) : base(cache)
{
_mediator = mediator;
}
[HttpGet]
[ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)]
+ [ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task Get(CancellationToken cancellationToken)
{
- return Ok(await _mediator.Send(new GetTags.Query(), cancellationToken));
+ return await CacheGetOrCreateAsync(() => _mediator.Send(new GetTags.Query(), cancellationToken));
}
}
}
\ No newline at end of file
diff --git a/services/Directory/FilterLists.Directory.Api/Startup.cs b/services/Directory/FilterLists.Directory.Api/Startup.cs
index 26aa4eccb..754d617e3 100644
--- a/services/Directory/FilterLists.Directory.Api/Startup.cs
+++ b/services/Directory/FilterLists.Directory.Api/Startup.cs
@@ -18,6 +18,7 @@ public Startup(IConfiguration configuration)
public void ConfigureServices(IServiceCollection services)
{
+ services.AddMemoryCache();
services.AddRouting(o => o.LowercaseUrls = true);
services.AddControllers()
.AddJsonOptions(o => o.JsonSerializerOptions.IgnoreNullValues = true);