MediatR Result Wrapper - ChrispyPeaches/FocusFriends GitHub Wiki
The MediatrResultWrapper
class is a wrapper allowing API MediatR features to communicate status codes and error messages to the controller calling the feature.
-
Type:
HttpStatusCode
-
Default Value:
null
- Description: Holds the http status code for the result.
-
Type:
string
-
Default Value:
null
- Description: Holds a message for the result if applicable (intended for errors).
-
Type:
T? (Generic)
-
Default Value:
null
- Description: The data that the result holds if applicable.
Anywhere that you would put the result class (ex: CreateUserResponse
), you would instead use MediatrResultWrapper<T>
where T is a class that the wrapper would attach an http status code and message to (ex: MediatrResultWrapper<CreateUserResponse>
). Additionally, you have the option of using this wrapper for the controller responses, or the controller could return an ActionResult using a refit ApiResponse wrapper (this is what is demonstrated in the examples) or something similar.
- Documentation for ActionResult linked here
- Docuemntation for ReactiveUI/Refit ApiResponse wrapper linked here
Note: Both of these are inside of FocusCore to share the classes between the App and API
// A query class for a MediatR feature using the MediatrResultWrapper for the response
public class GetUserQuery : IRequest<MediatrResultWrapper<GetUserResponse>>
{
public string? Auth0Id { get; set; }
...
}
// The associated response class
public class GetUserResponse
{
public BaseUser? User { get; set; }
...
}
// The Refit client endpoint.
// Note: This is using the refit ApiResponse wrapper so that an ActionResult return type can be used by the controller.
// This is the option used in this example, but alternatively you could return using the MediatrResultWrapper
[Get("/User/GetUser")]
Task<ApiResponse<GetUserResponse>> GetUserByAuth0Id(
GetUserQuery query,
CancellationToken cancellationToken = default);
// The associated API endpoint
// This is an example of how it can be used to communicate a response code from the MediatR feature to the controller so that it can log the response and return the appropriate status code
[HttpGet]
[Route("GetUser")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<GetUserResponse>> GetUserByAuth0Id(
[FromQuery] GetUserQuery query,
CancellationToken cancellationToken)
{
MediatrResultWrapper<GetUserResponse> result = new();
try
{
result = await _mediator.Send(query, cancellationToken);
}
catch (Exception ex)
{
_logger.LogError(ex, "[500]: Error getting user");
return StatusCode((int)HttpStatusCode.InternalServerError);
}
switch (result.HttpStatusCode)
{
case null:
return StatusCode((int)HttpStatusCode.InternalServerError);
case HttpStatusCode.OK:
return Ok(result.Data);
default:
_logger.LogError($"[{(int)result.HttpStatusCode}] {result.Message}");
return StatusCode((int)result.HttpStatusCode);
}
}
// Inside of the MediatR feature, the wrapper can be used to transmit a success like this example
return new()
{
HttpStatusCode = HttpStatusCode.OK,
Data = user
};
// Or it can be used to transmit an error like it is here
return new()
{
HttpStatusCode = HttpStatusCode.NotFound,
Message = $"User not found with Auth0Id: {query.Auth0Id}"
};