Neptunee.OperationResponse streamlines how you handle the response in your application. It eliminates complex if/else statements and offers multi-status support, a user-friendly API,validations checks, JSON compatibility, sync/async operations, and more. It's a clean way to manage the outcomes of your backend.
The code Inside your Controllers, ApiEndpoints or Command/Query Handlers will be more cleaner and readable.
Operation<Response>
.SuccessIf(request.Age >= 18, MyValidationErrors.AgeUnder18) // AgeUnder18 is new Error("Age must be 18 or older")
.OrFailureIf(request.Amount > 1000, MyValidationErrors.AmountOverMax) // AmountOverMax is new SpecificError("Amount","Over maximum")
.SetMessageOnFailure("One or more validation errors occur")
.SetMessageOnSuccess("It's work")
.OnSuccess(op =>
{
//your logic
})
.OnFailure(op => _logger.LogError("the logging"))
The Operation<Response>
Converted to IActionResult
For actions in the controllers or IResult
for the endpoint.
{
"IsSuccess": true,
"Message": "It's work",
"Response": {
// your response object
}
}
{
"IsSuccess": false,
"Message": "One or more validation errors occur",
"Errors": [
"Age must be 18 or older"
],
"SpecificErrors": [
{
"Code": "Amount",
"Description": "Over maximum"
}
]
}
Operation<TResponse>
Property | Type | Description |
---|---|---|
Message | string? |
An optional message providing additional information or context related to the operation. The default serialized message is the name of StatusCode (e.g., Ok, BadRequest, etc.). |
Response | TResponse? |
The actual response data of the operation. |
Errors | IReadOnlyCollection<Error> |
List of (Error or SpecificError) associated with the operation. |
HttpStatusCode | HttpStatusCode |
HttpStatusCode enum represents the HTTP status code returned by the operation. The default status Ok if errors property is empty or will be BadRequest . |
ExternalProps | ExternalProps |
ExternalProps object provides external properties provided based on the operation, actually it's a Dictionary<string,string> . |
IsSuccess | bool |
Indicates if the operation was successful. |
IsFailure | bool |
Indicates if the operation has failed. |
Method | Description |
---|---|
SetResponse(TResponse? response) |
Sets the response of the operation. |
SetMessage(string? message, bool overwrite = false) |
Sets the message related to the operation. |
SetMessageOnSuccess(string message, bool overwrite = false) |
Sets the message when operation is success. |
SetMessageOnFailure(string message, bool overwrite = false) |
Sets the message when operation is failure. |
SetStatusCode(HttpStatusCode statusCode) |
Sets the HTTP status code. |
Error(Error error) |
Adds an error to the operation. |
ExternalProp<TValue>(string key, TValue value) |
Adds an external property to the operation. |
OnSuccess(Action<Operation<TResponse>> action) |
Executes an action when operation is success. |
OnSuccessAsync(Func<Operation<TResponse>, Task> task) |
Asynchronously executes a task when operation is success. |
OnFailure(Action<Operation<TResponse>> action) |
Executes an action when operation is failure. |
OnFailureAsync(Func<Operation<TResponse>, Task> task) |
Asynchronously executes a task when operation is failure. |
Method | Description |
---|---|
Unknown() |
Creates an Operation<TResponse> with an unknown status. |
Ok(string? message = null) |
Creates a successful Operation<TResponse> with an optional message. |
BadRequest(string? message = null) |
Creates a failed Operation<TResponse> with an optional message. |
Result(Result result) |
Creates an Operation<TResponse> from an Result . |
Result(Result<TResponse> result) |
Creates an Operation<TResponse> from an Result with a response data. |
SuccessIf.Sync
Partial class Operation<TResponse>
.
Method | Description |
---|---|
OrSuccessIf(bool predicate, Action<Operation<TResponse>> onFalse) |
Executes the provided action onFalse on the current Operation<TResponse> if the provided boolean predicate is false , otherwise do nothing. |
OrSuccessIf(bool predicate, Error errorOnFalse) |
Adds the provided error errorOnFalse to the current Operation<TResponse> if the provided boolean predicate is false , otherwise do nothing. |
OrSuccessIf(Func<bool> predicate, Action<Operation<TResponse>> onFalse) |
Executes the provided action onFalse on the current Operation<TResponse> if the boolean result of the provided predicate function is false , otherwise do nothing. |
OrSuccessIf(Func<bool> predicate, Error errorOnFalse) |
Adds the provided error errorOnFalse to the current Operation<TResponse> if the boolean result of the provided predicate function is false , otherwise do nothing. |
OrIf(Result result) |
Modifies the current Operation<TResponse> based on the properties of the provided result . |
OrIf(Func<Result> result) |
Modifies the current Operation<TResponse> based on the properties of the provided result obtained through the function. |
AndSuccessIf(Func<bool> predicate, Action<Operation<TResponse>> onFalse) |
If the current Operation<TResponse> is still a success, executes the provided action onFalse on the current Operation<TResponse> if the boolean result of the provided predicate function is false , otherwise do nothing. |
AndSuccessIf(Func<bool> predicate, Error errorOnFalse) |
If the current Operation<TResponse> is still a success, adds the provided error errorOnFalse to the current Operation<TResponse> if the boolean result of the provided predicate function is false , otherwise do nothing. |
AndIf(Func<Result> result) |
If the current Operation<TResponse> is still a success, modifies it based on the properties of the provided result obtained through the function. |
Method | Description |
---|---|
SuccessIf(bool predicate, Action<Operation<TResponse>> onFalse) |
Creates a new unknown Operation<TResponse> , then executes the provided action onFalse on the current Operation<TResponse> if the provided boolean predicate is false , otherwise do nothing. |
SuccessIf(bool predicate, Error errorOnFalse) |
Creates a new unknown Operation<TResponse> , then adds the provided error errorOnFalse to the current Operation<TResponse> if the provided boolean predicate is false , otherwise do nothing. |
SuccessIf(Func<bool> predicate, Action<Operation<TResponse>> onFalse) |
Creates a new unknown Operation<TResponse> , then executes the provided action onFalse on the current Operation<TResponse> if the boolean result of the provided predicate function is false , otherwise do nothing. |
SuccessIf(Func<bool> predicate, Error errorOnFalse) |
Creates a new unknown Operation<TResponse> , then adds the provided error errorOnFalse to the current Operation<TResponse> if the boolean result of the provided predicate function is false , otherwise do nothing. |
If(Result result) |
Creates a new unknown Operation<TResponse> , then modifies the current Operation<TResponse> based on the properties of the provided result . |
SuccessIf.Async
Asynchronous of SuccessIf.Sync
.
Method |
---|
OrSuccessIfAsync(Func<Task<bool>> predicate, Action<Operation<TResponse>> onFalse) |
OrSuccessIfAsync(Func<Task<bool>> predicate, Error errorOnFalse) |
OrIfAsync(Func<Task<Result>> result) |
AndSuccessIfAsync(Func<Task<bool>> predicate, Action<Operation<TResponse>> onFalse) |
AndSuccessIfAsync(Func<Task<bool>> predicate, Error errorOnFalse) |
AndIfAsync(Func<Task<Result>> result) |
Method |
---|
SuccessIfAsync(Func<Task<bool>> predicate, Action<Operation<TResponse>> onFalse) |
SuccessIfAsync(Func<Task<bool>> predicate, Error errorOnFalse) |
FailureIf.Sync
Partial class Operation<TResponse>
.
Method | Description |
---|---|
OrFailureIf(bool predicate, Action<Operation<TResponse>> onTrue) |
Executes the provided action onTrue on the current Operation<TResponse> if the provided boolean predicate is true , otherwise do nothing. |
OrFailureIf(bool predicate, Error errorOnTrue) |
Adds the provided error errorOnTrue to the current Operation<TResponse> if the provided boolean predicate is true , otherwise do nothing. |
OrFailureIf(Func<bool> predicate, Action<Operation<TResponse>> onTrue) |
Executes the provided action onTrue on the current Operation<TResponse> if the boolean result of the provided predicate function is true , otherwise do nothing. |
OrFailureIf(Func<bool> predicate, Error errorOnTrue) |
Adds the provided error errorOnTrue to the current Operation<TResponse> if the boolean result of the provided predicate function is true , otherwise do nothing. |
AndFailureIf(Func<bool> predicate, Action<Operation<TResponse>> onTrue) |
If the current Operation<TResponse> is still a success, executes the provided action onTrue on the current Operation<TResponse> if the boolean result of the provided predicate function is true , otherwise do nothing. |
AndFailureIf(Func<bool> predicate, Error errorOnTrue) |
If the current Operation<TResponse> is still a success, adds the provided error errorOnTrue to the current Operation<TResponse> if the boolean result of the provided predicate function is true , otherwise do nothing. |
Method | Description |
---|---|
FailureIf(bool predicate, Action<Operation<TResponse>> onTrue) |
Creates a new unknown Operation<TResponse> , then executes the provided action onTrue on the current Operation<TResponse> if the provided boolean predicate is true , otherwise do nothing. |
FailureIf(bool predicate, Error errorOnTrue) |
Creates a new unknown Operation<TResponse> , then adds the provided error errorOnTrue to the current Operation<TResponse> if the provided boolean predicate is true , otherwise do nothing. |
FailureIf(Func<bool> predicate, Action<Operation<TResponse>> onTrue) |
Creates a new unknown Operation<TResponse> , then executes the provided action onTrue on the current Operation<TResponse> if the boolean result of the provided predicate function is true , otherwise do nothing. |
FailureIf(Func<bool> predicate, Error errorOnTrue) |
Creates a new unknown Operation<TResponse> , then adds the provided error errorOnTrue to the current Operation<TResponse> if the boolean result of the provided predicate function is true , otherwise do nothing. |
FailureIf.Async
Asynchronous of FailureIf.Sync
.
Method |
---|
OrFailureIfAsync(Func<Task<bool>> predicate, Action<Operation<TResponse>> onTrue) |
OrFailureIfAsync(Func<Task<bool>> predicate, Error errorOnTrue) |
AndFailureIfAsync(Func<Task<bool>> predicate, Action<Operation<TResponse>> onTrue) |
AndFailureIfAsync(Func<Task<bool>> predicate, Error errorOnTrue) |
Method |
---|
FailureIfAsync(Func<Task<bool>> predicate, Action<Operation<TResponse>> onTrue) |
FailureIfAsync(Func<Task<bool>> predicate, Error errorOnFalse) |
NoResponse
The NoResponse is abstract record to define that operation will not return actual response data.
Error
The Error
record represents a error with a textual description. It is commonly used to provide human-readable error messages.
Property | Type | Description |
---|---|---|
Description | string |
A textual description of the error. |
Method | Description |
---|---|
implicit operator Error(string description) |
Implicitly converts a string to an Error with the provided description. |
SpecificError
Inherits Error
.
Representing an error with both a code and a description. It is commonly used to provide more specific error information, such as in any prop or field it happened.
Property | Type | Description |
---|---|---|
Code | string |
A code associated with the error. |
Description | string |
A textual description of the error. |
Result
Use the Result
class in scenarios where you need to handle logic before passing the relevant information to the Operation<TResponse>
.
It used as an intermediary layer that can encapsulate and communicate information between services or methods.
Property | Type | Description |
---|---|---|
StatusCode | HttpStatusCode |
The HTTP status code associated with the result. |
Error | Error? |
An optional error associated with the result. |
Message | string? |
An optional message providing additional information or context related to the result. |
ExternalProps | Dictionary<string, string> |
Additional external properties provided as key-value pairs. |
IsSuccess | bool |
Indicates if the result represents a successful operation, typically when the StatusCode falls within the range of 200-299. |
IsFailure | bool |
Indicates if the result represents a failed operation, typically when the StatusCode does not fall within the range of 200-299. |
Method | Description |
---|---|
To<TValue>() |
Converts the Result to an Result<TValue> without providing a value. |
To<TValue>(TValue value) |
Converts the Result to an Result<TValue> and provides a value. |
Method | Description |
---|---|
With(HttpStatusCode statusCode, Error? error = null, string? message = null, Dictionary<string, string> externalProps = null) |
Creates a new Result with the specified properties. |
Ok(string? message = null, Dictionary<string, string> externalProps = null) |
Creates a successful Result with an optional message and external properties. |
BadRequest(Error? error = null, string? message = null, Dictionary<string, string> externalProps = null) |
Creates a failed Result with an optional error, message, and external properties. |
Result<TValue>
Inherits Result
.
Use Result<TValue>
in case there are TValue
will returned.
Property | Type | Description |
---|---|---|
Value | TValue |
representing the actual return data. |
HasValue | bool |
Indicates if the Value has a non-null value. |
Method | Description |
---|---|
ValueOrDefault() |
Retrieves the Value if it has a non-null value, or returns null if the Value is null . |
Operator | Description |
---|---|
implicit operator TValue(Result<TValue> result) |
Implicitly converts an Result<TValue> to its Value . |
implicit operator Result<TValue>(TValue value) |
Implicitly converts a TValue to a successful Result<TValue> containing the provided value. |
OperationSettings
Provides a central place to manage and configure settings related to the serialization of Operation<TResponse>
objects.
Property | Type | Description |
---|---|---|
JsonSerializerOptions | JsonSerializerOptions |
The JSON serialization options used for custom serialization of Operation<TResponse> . |
Method | Description |
---|---|
ResetConverterFactory(JsonConverterFactory converterFactory) |
Resets the JSON converter factory for Operation<TResponse> . |
ResetConverterFactory<TJsonConverter>() |
Resets the JSON converter factory for Operation<TResponse> . |
ResetErrorConverter(JsonConverter<IReadOnlyCollection<Error>> converter) |
Resets the JSON converter for IReadOnlyCollection<Error> . |
ResetErrorConverter<TJsonConverter>() |
Resets the JSON converter for IReadOnlyCollection<Error> . |
ResetExternalPropsConverter(JsonConverter<ExternalProps> converter) |
Resets the JSON converter for ExternalProps . |
ResetExternalPropsConverter<TJsonConverter>() |
Resets the JSON converter for ExternalProps . |
Use the OperationSettings
class to configure the JSON serialization options for Operation<TResponse>
and to
manage custom JSON converters.
OperationServiceCollectionExtensions
Offers extension methods for configuring the Operation<TResponse>
JSON serialization options within MVC and HTTP serialization options in ASP.NET Core.
Method | Description |
---|---|
AddOperationSerializerOptions(JsonConverterFactory? operationJsonConverterFactory = null, JsonConverter<IReadOnlyCollection<Error>>? errorJsonConverter = null, JsonConverter<ExternalProps>? externalPropsJsonConverter = null, Action<JsonSerializerOptions>? action = null) |
Configures JSON serialization options for Operation<TResponse> and related objects within the service collection. |
Use the OperationServiceCollectionExtensions
class when you want to configure JSON serialization options for your ASP.NET Core application, especially when working with Operation<TResponse>
and related types.
OperationWrapper
Method | Description |
---|---|
ToIActionResult<TResponse>(this Operation<TResponse> Operation<TResponse>, object? serializerSettings = null) |
Converts an Operation<TResponse> to a JsonResult . |
ToIActionResultAsync<TResponse>(this Task<Operation<TResponse>> task, object? serializerSettings = null) |
Asynchronously converts an Operation<TResponse> to a JsonResult . |
ToIResult<TResponse>(this Operation<TResponse> Operation<TResponse>,JsonSerializerOptions? options = null) |
Converts an Operation<TResponse> to a Results.Json (supported in .NET 6.0 or greater). |
ToIResultAsync<TResponse>(this Task<Operation<TResponse>> task,JsonSerializerOptions? options = null) |
Asynchronously converts Operation<TResponse> to a Results.Json (supported in .NET 6.0 or greater). |
ToOperation<TResponse>(this IdentityResult identityResult) |
Converts an IdentityResult to an Operation<TResponse> . |
How to validate and set errors
There are bunch of ways to validate your operation (check out all methods in Schema).
For defining errors there are 3 ways:
Error(string Description)
record.SpecificError(string Code,string Description)
record inheritsError(string Description)
.string
implicit convert toError(string Description)
.
All errors set to List<Error>
.
public class SampleRequestHandler : IRequestHandler<Request,Operation<NoResponse>>
{
// ctor and injections
public async Task<Operation<NoResponse>> HandelAsync(Request request)
=> await Operation
.SuccessIf(request.Prop == true, "the error") // way 1
.OrFailureIf(() => request.Prop == true, new Error("the error")) // way 2
.OrFailureIf(request.Prop == true, new SpecificError("the code", "description")) // way 3
.AndFailureIfAsync(async () => await _service.IsGoneAsync(), op =>
{
//case: logic if this error occur
op.SetStatusCode(HttpStatusCode.Gone);
op.Error(/* chose way you like */);
})
.OnSuccessAsync(op =>
{
// your logic
});
}
The deference between Or
/ And
methods is the And
methods check if Operation<TResponse>
is still success before execute, otherwise will skip.
So you may use And
in case you have expensive check that you only want to check when everything else is alright.
How to set status code
You can use SetStatusCode()
method to set custom status code you need.
No need to set the Ok & BadRequest status because will automatically set if the Errors
property was empty or not.
public Operation<NoResponse> Handel(Request request)
=> Operation<NoResponse>
.IfSuccsus(/* passing params */)
.OnSuccess(op =>
{
op.SetStatusCode(HttpStatusCode.Created);
// logic
});
public Operation<NoResponse> Handel(Request request)
{
// logic
retrun Operation<NoResponse>.SetStatusCode(HttpStatusCode.Continue)
}
How to set message
public class SampleRequestHandler : IRequestHandler<Request,Operation>
{
// ctor and injections
public async Task<Operation<NoResponse>> HandelAsync(Request request)
=> await Operation
.SuccessIf(request.Prop == true, "the error") // way 1
.OrFailureIf(request.Prop == true, new Error("the error")) // way 2
.OrFailureIf(request.Prop == true, new SpecificError("the code", "description")) // way 3
.AndFailureIfAsync(async () => await _service.IsGoneAsync(), op =>
{
// case: logic if this error occur
op.SetStatusCode(HttpStatusCode.Gone);
op.Error(/* chose way you like */);
})
+ .SetMessageOnSuccess("your succses message") // way 1
+ .SetMessageOnFailure("your failure message") // way 2
+ .SetMessage("your message") // way 3
.OnSuccessAsync(op =>
{
// your logic
});
}
This setters check if the message is null first, so like the example above the SetMessage()
will not execute but the
setters has optional parameter bool overwrite = false
can make it execute (SetMessage("your message",true)
) in your rare case.
How to set response
You can use SetResponse()
method to set the actual data of the operation or just return the response that will implicitly convert to Operation<TResponse>
with 200
as status code and OK
as message.
public Operation<Response> Handel(Request request)
=> Operation<Response>
.IfSuccsus(/* passing params */)
.OnSuccess(op =>
{
// logic
op.SetResponse(new Response(/* passing params */));
});
public Operation<Response> Handel(Request request)
{
// logic
retrun new Response(/* passing params */);
}
How to serialize
When serialize Operation<TResponse>
must use JsonSerializerOptions
in OperationSettings.
JsonSerializer.Serialize(operation, OperationSettings.JsonSerializerOptions);
To configure these options for MVC and HTTP serialization in ASP.NET Core. In other words, to use them when calling ToIActionResult()
or ToIResult()
should use:
bulider.Services.AddOperationSerializerOptions();
You can also change the default converters or options using OperationSettings
methods, check the schema here.
OperationSettings.ResetErrorConverter<IgnoreEmptyCombineErrorConverter>();
or pass to optional parameters in AddOperationSerializerOptions()
:
bulider.Services.AddOperationSerializerOptions(externalPropsJsonConverter: new ExternalPropsConverter());
The JsonSerializerOptions
has 3 JSON converts for Operation, ExternalProps and Errors.
P.S: can check the available JSON converters in Custom JSON converters bellow.
Custom JSON converters
The custom JSON converters divided to:
- Operation
- OperationConverter with Factory (the default):
IsSuccess
: serialize to boolean.Message
: serialize to string if is not null otherwise to name of status code.Response
: serialize to object if is not null otherwise ignore it.Errors
: serialize depends on the custom converter provided (the default:IgnoreEmptySplitErrorConverter
).ExtrenalProps
: serialize depends on the custom converter provided (the default:IgnoreEmptyExternalPropsConverter
).
{ "IsSuccess": true, "Message": "OK" }
{ "IsSuccess": false, "Message": "BadRequest", "Errors": [ "the error" ] }
{ "IsSuccess": true, "Message": "Custom message", "Response": { // The actual response object } }
- OperationConverter with Factory (the default):
- ExternalProps
- ExternalPropsConverter:
ExternalProps
: serialize to object.
{ "IsSuccess": true, "Message": "OK", "ExternalProps": { "key": "value" } }
{ "IsSuccess": true, "Message": "OK", "ExternalProps": {} }
- IgnoreEmptyExternalPropsConverter (the default):
ExternalProps
: serialize to object if are not empty otherwise ignore it.
{ "IsSuccess": true, "Message": "OK", "ExternalProps": { "key": "value" } }
{ "IsSuccess": true, "Message": "OK" }
- ExternalPropsConverter:
- Errors
- SplitErrorConverter:
Errors
: serialize the Error(string Description) to list of strings.SpecificErrors
: serialize the SpecificError(string Code,string Description) to list of objects.
{ "IsSuccess": false, "Message": "BadRequest", "Errors": [ "the error" ], "SpecificErrors": [ { "Code": "The Code", "Description": "The Description" } ] }
{ "IsSuccess": true, "Message": "OK", "Errors": [], "SpecificErrors": [] }
- CombineErrorConverter:
Errors
: serialize to list of strings by convertingSpecificError(string Code,string Description)
object to$"{Code} : {Description}"
string.
{ "IsSuccess": false, "Message": "BadRequest", "Errors": [ "the error", "The Code : The Description" ] }
{ "IsSuccess": true, "Message": "OK", "Errors": [] }
- IgnoreEmptySplitErrorConverter (the default):
Errors
: serialize the Error(string Description) to list of strings if are not empty otherwise ignore it..SpecificErrors
: serialize the SpecificError(string Code,string Description) to list of objects if are not empty otherwise ignore it.
{ "IsSuccess": false, "Message": "BadRequest", "Errors": [ "the error" ], "SpecificErrors": [ { "Code": "The Code", "Description": "The Description" } ] }
{ "IsSuccess": false, "Message": "BadRequest", "Errors": [ "the error" ] }
{ "IsSuccess": true, "Message": "OK" }
- IgnoreEmptyCombineErrorConverter:
Errors
: serialize to list of strings by convertingSpecificError(string Code,string Description)
object to$"{Code} : {Description}"
string if are not empty otherwise ignore it.
{ "IsSuccess": false, "Message": "BadRequest", "Errors": [ "The Code : The Description" ] }
{ "IsSuccess": true, "Message": "OK" }
- SplitErrorConverter:
Let say we have
public record SingUpRequest(string Email, string Password);
public record SingUpResponse(Guid Id);
public static class Errors
{
public static class Users
{
public static Error EmailAlreadyExists = "Email is already used";
}
}
DI registration
bulider.Services.AddOperationSerializerOptions();
Logic
public class SingUpRequestHandler : IRequestHandler<SingUpRequest, Operation<SingUpResponse>>
{
private readonly IUserService _userService;
public SingUpRequestHandler(IuserService userService)
{
_userService = userService;
}
public async Task<Operation<SingUpResponse>> HandelAsync(SingUpRequest request) // #1
=> await Operation<SingUpResponse>
.FailureIf(await _userService.IsEmailExistsAsync(request.Email), Errors.Users.EmailAlreadyExists)
// .FailureIf(await userService.IsEmailExistsAsync(request.Email), new Error("Email is already used")) #2
// .FailureIf(await userService.IsEmailExistsAsync(request.Email), "Email is already used") #3
// .FailureIf(await userService.IsEmailExistsAsync(request.Email), new SpecificError("Email","already used")) #4
// .FailureIf(await userService.IsEmailExistsAsync(request.Email), op => op.Error(Errors.Users.EmailAlreadyExists)) #5 and more
.OnSuccessAsync(async op =>
{
var user = new User(request.Email);
await _userService.CraeteAsync(request.Email, request.Password);
op.SetResponse(new SingUpResponse(user.Id));
});
public async Task<Operation<SingUpResponse>> HandelAsync(SingUpRequest request) // #2
{
if (await _userService.IsEmailExistsAsync(request.Email))
{
return Errors.Users.EmailAlreadyExists; // #1 implicit conversion
// return Operation<SingUpResponse>.BadRequest().Error(Errors.Users.EmailAlreadyExists); #2
}
var user = new User(request.Email);
await _userService.CraeteAsync(request.Email, request.Password);
return new SingUpResponse(user.Id); // #1 implicit conversion
// return Operation<SingUpResponse>.Ok().SetResponse(new SingUpResponse(user.Id)); #2
}
}
Controllers APIs
public class UsersController : BaseController
{
[HttpPost]
public async Task<IActionResult> SingUp([FromBody] SingUpRequest request, [FromServices] IRequestHandler<SingUpRequest, Operation<SingUpResponse>> handler)
=> await handler.HandelAsync(request).ToIActionResultAsync();
}
Minimal APIs
app.MapPost("/users/singUp", async ([FromBody] SingUpRequest request, [FromServices] IRequestHandler<SingUpRequest, Operation<SingUpResponse>> handler)
=> await handler.HandelAsync(request).ToIResultAsync());
Outputs
{
"IsSuccess": true,
"Message": "Ok",
"Response": {
"Id": "7BA82D5E-5A84-463B-80A1-34D923F9B027"
}
}
{
"IsSuccess": false,
"Message": "BadRequest",
"Errors": [
"Email is already used"
]
}