feat(dir): scaffold GET Change by Id endpoint

ref https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/1607
This commit is contained in:
Collin M. Barrett 2021-11-26 15:56:39 -06:00
parent a51f6faa6a
commit fec59aaf6d
4 changed files with 87 additions and 7 deletions

View file

@ -20,9 +20,23 @@ public ChangesController(IMemoryCache cache, IMediator mediator) : base(cache)
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The changes.</returns>
[HttpGet]
[ProducesResponseType(typeof(List<GetChanges.ChangesVm>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(List<GetChanges.ChangeVm>), StatusCodes.Status200OK)]
public Task<IActionResult> Get(CancellationToken cancellationToken)
{
return CacheGetOrCreateAsync(() => _mediator.Send(new GetChanges.Query(), cancellationToken));
}
/// <summary>
/// Gets the change.
/// </summary>
/// <param name="id">The identifier of the change.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The change.</returns>
[HttpGet("{id:long}")]
[ProducesResponseType(typeof(GetChange.ChangeVm), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public Task<IActionResult> GetDetails(long id, CancellationToken cancellationToken)
{
return CacheGetOrCreateAsync(() => _mediator.Send(new GetChange.Query(id), cancellationToken), id);
}
}

View file

@ -26,6 +26,9 @@ public static void AddSwaggerGen(this IServiceCollection services)
}
});
// Swagger UI struggles with lookups of nested types represented by concatenated '+'
o.CustomSchemaIds(t => t.FullName?.Replace("+", "."));
var apiXmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
o.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, apiXmlFile));

View file

@ -0,0 +1,63 @@
using System.Text.Json;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using FilterLists.Directory.Domain.Aggregates;
using FilterLists.Directory.Infrastructure.Persistence.Queries.Context;
using FilterLists.Directory.Infrastructure.Persistence.Queries.Entities;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace FilterLists.Directory.Application.Queries;
public static class GetChange
{
public record Query(long Id) : IRequest<ChangeVm?>;
internal class Handler : IRequestHandler<Query, ChangeVm?>
{
private readonly IQueryContext _context;
private readonly IMapper _mapper;
public Handler(IQueryContext context, IMapper mapper)
{
_context = context;
_mapper = mapper;
}
public Task<ChangeVm?> Handle(Query request, CancellationToken cancellationToken)
{
return _context.Changes
.Where(c => c.Id == request.Id)
.ProjectTo<ChangeVm>(_mapper.ConfigurationProvider)
.SingleOrDefaultAsync(cancellationToken);
}
}
internal class ChangesVmProfile : Profile
{
public ChangesVmProfile()
{
CreateMap<Change, ChangeVm>();
}
}
public record ChangeVm
{
public long Id { get; private init; }
public string? Reason { get; private init; }
public DateTime SubmittedAt { get; private init; }
public DateTime? ApprovedAt { get; private init; }
public DateTime? RejectedAt { get; private init; }
public string? RejectedReason { get; private init; }
public JsonDocument? Before { get; private init; }
public JsonDocument? After { get; private init; }
public AggregateType AggregateType { get; private init; }
public long? FilterListId { get; private init; }
public long? LanguageId { get; private init; }
public long? LicenseId { get; private init; }
public long? MaintainerId { get; private init; }
public long? SoftwareId { get; private init; }
public long? SyntaxId { get; private init; }
public long? TagId { get; private init; }
}
}

View file

@ -11,9 +11,9 @@ namespace FilterLists.Directory.Application.Queries;
public static class GetChanges
{
public record Query : IRequest<List<ChangesVm>>;
public record Query : IRequest<List<ChangeVm>>;
internal class Handler : IRequestHandler<Query, List<ChangesVm>>
internal class Handler : IRequestHandler<Query, List<ChangeVm>>
{
private readonly IQueryContext _context;
private readonly IMapper _mapper;
@ -24,12 +24,12 @@ public Handler(IQueryContext context, IMapper mapper)
_mapper = mapper;
}
public Task<List<ChangesVm>> Handle(Query request, CancellationToken cancellationToken)
public Task<List<ChangeVm>> Handle(Query request, CancellationToken cancellationToken)
{
return _context.Changes
.Where(c => c.ApprovedAt == null && c.RejectedAt == null)
.OrderBy(c => c.SubmittedAt)
.ProjectTo<ChangesVm>(_mapper.ConfigurationProvider)
.ProjectTo<ChangeVm>(_mapper.ConfigurationProvider)
.ToListAsync(cancellationToken);
}
}
@ -38,11 +38,11 @@ internal class ChangesVmProfile : Profile
{
public ChangesVmProfile()
{
CreateMap<Change, ChangesVm>();
CreateMap<Change, ChangeVm>();
}
}
public record ChangesVm
public record ChangeVm
{
public long Id { get; private init; }
public string? Reason { get; private init; }