Skip to content

Latest commit

 

History

History
128 lines (108 loc) · 4.08 KB

File metadata and controls

128 lines (108 loc) · 4.08 KB

BusinessResultEndpoint

Package: ModEndpoints

A BusinessResultEndpoint implementation, after handling request, encapsulates the business result of HandleAsync method in a HTTP 200 Minimal API IResult and sends to client. The business result returned may be in Ok or Failed state. This behaviour makes BusinessResultEndpoints more suitable for cases where clients are aware of Result or Result<TValue> implementations.

Request model (if any) defined for a BusinessResultEndpoint is bound with [AsParameters] attribute.

  • BusinessResultEndpoint<TRequest, TResultValue>: Has a request model, supports request validation and returns a Result<TResultValue> within HTTP 200 IResult.
public record GetStoreByIdRequest(Guid Id);

public record GetStoreByIdResponse(Guid Id, string Name);

internal class GetStoreByIdRequestValidator : AbstractValidator<GetStoreByIdRequest>
{
  public GetStoreByIdRequestValidator()
  {
    RuleFor(x => x.Id).NotEmpty();
  }
}

internal class GetStoreById
  : BusinessResultEndpoint<GetStoreByIdRequest, GetStoreByIdResponse>
{
  protected override void Configure(
    EndpointConfigurationBuilder builder,
    EndpointConfigurationContext configurationContext)
  {
    builder.MapGet("/{Id}");
  }

  protected override async Task<Result<GetStoreByIdResponse>> HandleAsync(
    GetStoreByIdRequest req,
    CancellationToken ct)
  {
    await Task.CompletedTask; // Simulate async work

    return new GetStoreByIdResponse(
        Id: req.Id,
        Name: "Name 1");
  }
}
  • BusinessResultEndpoint<TRequest>: Has a request model, supports request validation and returns a Result within HTTP 200 IResult.
public record UpdateStoreRequest(Guid Id, [FromBody] UpdateStoreRequestBody Body);

public record UpdateStoreRequestBody(string Name);

internal class UpdateStoreRequestValidator : AbstractValidator<UpdateStoreRequest>
{
  public UpdateStoreRequestValidator()
  {
    RuleFor(x => x.Id).NotEmpty();
    RuleFor(x => x.Body.Name).NotEmpty();
  }
}

internal class UpdateStore
  : BusinessResultEndpoint<UpdateStoreRequest>
{
  protected override void Configure(
    EndpointConfigurationBuilder builder,
    EndpointConfigurationContext configurationContext)
  {
    builder.MapPut("/{Id}");
  }

  protected override Task<Result> HandleAsync(
    UpdateStoreRequest req,
    CancellationToken ct)
  {
    return Task.FromResult(Result.Ok());
  }
}
  • BusinessResultEndpointWithEmptyRequest<TResultValue>: Doesn't have a request model and returns a Result<TResultValue> within HTTP 200 IResult.
public record ListStoresResponse(List<ListStoresResponseItem> Stores);
public record ListStoresResponseItem(Guid Id, string Name);

internal class ListStores
  : BusinessResultEndpointWithEmptyRequest<ListStoresResponse>
{
  protected override void Configure(
    EndpointConfigurationBuilder builder,
    EndpointConfigurationContext configurationContext)
  {
    builder.MapGet("/");
  }

  protected override async Task<Result<ListStoresResponse>> HandleAsync(
    CancellationToken ct)
  {
    await Task.CompletedTask; // Simulate async work

    return new ListStoresResponse(Stores:
      [
        new ListStoresResponseItem(Guid.NewGuid(), "Name 1"),
        new ListStoresResponseItem(Guid.NewGuid(), "Name 2")
      ]);
  }
}
  • BusinessResultEndpointWithEmptyRequest: Doesn't have a request model and returns a Result within HTTP 200 IResult.
internal class ResultEndpointWithEmptyRequest
  : BusinessResultEndpointWithEmptyRequest
{
  protected override void Configure(
    EndpointConfigurationBuilder builder,
    EndpointConfigurationContext configurationContext)
  {
    builder.MapDelete("/");
  }

  protected override async Task<Result> HandleAsync(
    CancellationToken ct)
  {
    await Task.CompletedTask; // Simulate async work
    return Result.Ok();
  }
}