Skip to content

Commit

Permalink
better problem detail support in endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
pwelter34 committed Nov 14, 2024
1 parent 09c4715 commit f57a930
Show file tree
Hide file tree
Showing 20 changed files with 364 additions and 152 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
namespace Tracker.WebService.Domain;

[JsonSourceGenerationOptions(
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull,
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
#region Generated Attributes
[JsonSerializable(typeof(AuditReadModel))]
Expand Down Expand Up @@ -51,7 +51,7 @@ namespace Tracker.WebService.Domain;
[JsonSerializable(typeof(UserUpdateModel))]
[JsonSerializable(typeof(EntityQuery))]
[JsonSerializable(typeof(EntitySelect))]
[JsonSerializable(typeof(JsonPatchDocument))]
[JsonSerializable(typeof(IJsonPatchDocument))]
#endregion
public partial class DomainJsonContext : JsonSerializerContext
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
using System;
using MediatR;
using MediatR.CommandQuery.Endpoints;

using Microsoft.Extensions.Logging;

using Tracker.WebService.Domain.Models;

namespace Tracker.WebService.Endpoints;

[RegisterTransient<IFeatureEndpoint>(Duplicate = DuplicateStrategy.Append)]
public class AuditEndpoint : EntityCommandEndpointBase<Guid, AuditReadModel, AuditReadModel, AuditCreateModel, AuditUpdateModel>
{
public AuditEndpoint(IMediator mediator) : base(mediator, "Audit")
public AuditEndpoint(ILoggerFactory loggerFactory, IMediator mediator)
: base(loggerFactory, mediator, "Audit")
{

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
using System;
using MediatR;
using MediatR.CommandQuery.Endpoints;
using Microsoft.Extensions.Logging;

using Tracker.WebService.Domain.Models;

namespace Tracker.WebService.Endpoints;

[RegisterTransient<IFeatureEndpoint>(Duplicate = DuplicateStrategy.Append)]
public class PriorityEndpoint : EntityCommandEndpointBase<Guid, PriorityReadModel, PriorityReadModel, PriorityCreateModel, PriorityUpdateModel>
{
public PriorityEndpoint(IMediator mediator) : base(mediator, "Priority")
public PriorityEndpoint(ILoggerFactory loggerFactory, IMediator mediator)
: base(loggerFactory, mediator, "Priority")
{

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
using System;
using MediatR;
using MediatR.CommandQuery.Endpoints;

using Microsoft.Extensions.Logging;

using Tracker.WebService.Domain.Models;

namespace Tracker.WebService.Endpoints;

[RegisterTransient<IFeatureEndpoint>(Duplicate = DuplicateStrategy.Append)]
public class RoleEndpoint : EntityCommandEndpointBase<Guid, RoleReadModel, RoleReadModel, RoleCreateModel, RoleUpdateModel>
{
public RoleEndpoint(IMediator mediator) : base(mediator, "Role")
public RoleEndpoint(ILoggerFactory loggerFactory, IMediator mediator)
: base(loggerFactory, mediator, "Role")
{

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
using System;
using MediatR;
using MediatR.CommandQuery.Endpoints;

using Microsoft.Extensions.Logging;

using Tracker.WebService.Domain.Models;

namespace Tracker.WebService.Endpoints;

[RegisterTransient<IFeatureEndpoint>(Duplicate = DuplicateStrategy.Append)]
public class StatusEndpoint : EntityCommandEndpointBase<Guid, StatusReadModel, StatusReadModel, StatusCreateModel, StatusUpdateModel>
{
public StatusEndpoint(IMediator mediator) : base(mediator, "Status")
public StatusEndpoint(ILoggerFactory loggerFactory, IMediator mediator)
: base(loggerFactory, mediator, "Status")
{

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
using System;
using MediatR;
using MediatR.CommandQuery.Endpoints;

using Microsoft.Extensions.Logging;

using Tracker.WebService.Domain.Models;

namespace Tracker.WebService.Endpoints;

[RegisterTransient<IFeatureEndpoint>(Duplicate = DuplicateStrategy.Append)]
public class TaskEndpoint : EntityCommandEndpointBase<Guid, TaskReadModel, TaskReadModel, TaskCreateModel, TaskUpdateModel>
{
public TaskEndpoint(IMediator mediator) : base(mediator, "Task")
public TaskEndpoint(ILoggerFactory loggerFactory, IMediator mediator)
: base(loggerFactory, mediator, "Task")
{

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
using System;
using MediatR;
using MediatR.CommandQuery.Endpoints;

using Microsoft.Extensions.Logging;

using Tracker.WebService.Domain.Models;

namespace Tracker.WebService.Endpoints;

[RegisterTransient<IFeatureEndpoint>(Duplicate = DuplicateStrategy.Append)]
public class UserEndpoint : EntityCommandEndpointBase<Guid, UserReadModel, UserReadModel, UserCreateModel, UserUpdateModel>
{
public UserEndpoint(IMediator mediator) : base(mediator, "User")
public UserEndpoint(ILoggerFactory loggerFactory, IMediator mediator)
: base(loggerFactory, mediator, "User")
{

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
using System;
using MediatR;
using MediatR.CommandQuery.Endpoints;

using Microsoft.Extensions.Logging;

using Tracker.WebService.Domain.Models;

namespace Tracker.WebService.Endpoints;

[RegisterTransient<IFeatureEndpoint>(Duplicate = DuplicateStrategy.Append)]
public class UserLoginEndpoint : EntityCommandEndpointBase<Guid, UserLoginReadModel, UserLoginReadModel, UserLoginCreateModel, UserLoginUpdateModel>
{
public UserLoginEndpoint(IMediator mediator) : base(mediator, "UserLogin")
public UserLoginEndpoint(ILoggerFactory loggerFactory, IMediator mediator)
: base(loggerFactory, mediator, "UserLogin")
{

}
Expand Down
2 changes: 2 additions & 0 deletions samples/Tracker.WebService.EntityFrameworkCore/generation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ project:
database:
provider: SqlServer
connectionString: 'Data Source=(local);Initial Catalog=TrackerService;Integrated Security=True;TrustServerCertificate=True'
schemas:
- dbo
data:
context:
name: '{Database.Name}Context'
Expand Down
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
<ItemGroup>
<PackageReference Include="AssemblyMetadata.Generators" Version="2.1.0" PrivateAssets="All" />
<PackageReference Include="MinVer" Version="6.0.0" PrivateAssets="All" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.177" PrivateAssets="All" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.178" PrivateAssets="All" />
</ItemGroup>

<ItemGroup>
Expand Down
21 changes: 16 additions & 5 deletions src/MediatR.CommandQuery.Endpoints/DispatcherEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace MediatR.CommandQuery.Endpoints;
Expand All @@ -14,11 +16,17 @@ public class DispatcherEndpoint : IFeatureEndpoint
{
private readonly ISender _sender;
private readonly DispatcherOptions _dispatcherOptions;
private readonly ILogger<DispatcherEndpoint> _logger;

public DispatcherEndpoint(ISender sender, IOptions<DispatcherOptions> dispatcherOptions)
public DispatcherEndpoint(ILogger<DispatcherEndpoint> logger, ISender sender, IOptions<DispatcherOptions> dispatcherOptions)
{
ArgumentNullException.ThrowIfNull(logger);
ArgumentNullException.ThrowIfNull(sender);
ArgumentNullException.ThrowIfNull(dispatcherOptions);

_sender = sender;
_dispatcherOptions = dispatcherOptions.Value;
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}

public void AddRoutes(IEndpointRouteBuilder app)
Expand All @@ -28,27 +36,30 @@ public void AddRoutes(IEndpointRouteBuilder app)

group
.MapPost(_dispatcherOptions.SendRoute, Send)
.WithTags("Dispatcher")
.WithEntityMetadata("Dispatcher")
.WithName($"Send")
.WithSummary("Send Mediator command")
.WithDescription("Send Mediator command");
}

protected virtual async Task<IResult> Send(
protected virtual async Task<Results<Ok<object>, ProblemHttpResult>> Send(
[FromBody] DispatchRequest dispatchRequest,
ClaimsPrincipal? user = default,
CancellationToken cancellationToken = default)
{
try
{
var request = dispatchRequest.Request;

var result = await _sender.Send(request, cancellationToken).ConfigureAwait(false);
return Results.Ok(result);
return TypedResults.Ok(result);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error dispatching request: {ErrorMessage}", ex.Message);

var details = ex.ToProblemDetails();
return Results.Problem(details);
return TypedResults.Problem(details);
}
}
}
Loading

0 comments on commit f57a930

Please sign in to comment.