mirror of
https://github.com/collinbarrett/FilterLists.git
synced 2026-03-11 09:04:27 +00:00
feat(directory): ✨⚡ add in-memory api caching
This commit is contained in:
parent
2a51819b43
commit
9cb9cc1cf6
9 changed files with 72 additions and 22 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
/// <remarks>https://stackoverflow.com/a/52506210/2343739</remarks>
|
||||
protected async Task<IActionResult> CacheGetOrCreateAsync<TResponse>(
|
||||
Func<Task<TResponse>> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<GetLanguages.LanguageVm>), (int)HttpStatusCode.OK)]
|
||||
[ProducesResponseType((int)HttpStatusCode.NotFound)]
|
||||
public async Task<IActionResult> Get(CancellationToken cancellationToken)
|
||||
{
|
||||
return Ok(await _mediator.Send(new GetLanguages.Query(), cancellationToken));
|
||||
return await CacheGetOrCreateAsync(() => _mediator.Send(new GetLanguages.Query(), cancellationToken));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<GetLicenses.LicenseVm>), (int)HttpStatusCode.OK)]
|
||||
[ProducesResponseType((int)HttpStatusCode.NotFound)]
|
||||
public async Task<IActionResult> Get(CancellationToken cancellationToken)
|
||||
{
|
||||
return Ok(await _mediator.Send(new GetLicenses.Query(), cancellationToken));
|
||||
return await CacheGetOrCreateAsync(() => _mediator.Send(new GetLicenses.Query(), cancellationToken));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<GetLists.ListVm>), (int)HttpStatusCode.OK)]
|
||||
[ProducesResponseType((int)HttpStatusCode.NotFound)]
|
||||
public async Task<IActionResult> 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<IActionResult> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<GetMaintainers.MaintainerVm>), (int)HttpStatusCode.OK)]
|
||||
[ProducesResponseType((int)HttpStatusCode.NotFound)]
|
||||
public async Task<IActionResult> Get(CancellationToken cancellationToken)
|
||||
{
|
||||
return Ok(await _mediator.Send(new GetMaintainers.Query(), cancellationToken));
|
||||
return await CacheGetOrCreateAsync(() => _mediator.Send(new GetMaintainers.Query(), cancellationToken));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<GetSoftware.SoftwareVm>), (int)HttpStatusCode.OK)]
|
||||
[ProducesResponseType((int)HttpStatusCode.NotFound)]
|
||||
public async Task<IActionResult> Get(CancellationToken cancellationToken)
|
||||
{
|
||||
return Ok(await _mediator.Send(new GetSoftware.Query(), cancellationToken));
|
||||
return await CacheGetOrCreateAsync(() => _mediator.Send(new GetSoftware.Query(), cancellationToken));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<GetSyntaxes.SyntaxVm>), (int)HttpStatusCode.OK)]
|
||||
[ProducesResponseType((int)HttpStatusCode.NotFound)]
|
||||
public async Task<IActionResult> Get(CancellationToken cancellationToken)
|
||||
{
|
||||
return Ok(await _mediator.Send(new GetSyntaxes.Query(), cancellationToken));
|
||||
return await CacheGetOrCreateAsync(() => _mediator.Send(new GetSyntaxes.Query(), cancellationToken));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<GetTags.TagVm>), (int)HttpStatusCode.OK)]
|
||||
[ProducesResponseType((int)HttpStatusCode.NotFound)]
|
||||
public async Task<IActionResult> Get(CancellationToken cancellationToken)
|
||||
{
|
||||
return Ok(await _mediator.Send(new GetTags.Query(), cancellationToken));
|
||||
return await CacheGetOrCreateAsync(() => _mediator.Send(new GetTags.Query(), cancellationToken));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue