-
Notifications
You must be signed in to change notification settings - Fork 10.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Minimal API: TypedResults, Problem, ValidationProblem #59560
Comments
I think this approach may not work well with the generation of OpenAPI documents that was added in .NET 9. In particular, I think it would require |
@mikekistler right, thx I was convinced that TypedResults.Problem will provide the ProblemDetails model in OpenID doc. Other TypedResults. are working but not TypedResults.Problem... I just confirmed now and I m sad... ;) |
@mikekistler I changed for something like that, but it's bad: public static BadRequest<ProblemDetails> Problem(IFeatureError featureError)
{
ArgumentNullException.ThrowIfNull(featureError);
var problemDetails = new ProblemDetails()
{
Detail = featureError.Details,
Status = (int)featureError.ErrorType,
Title = "Service - feature error",
Extensions = { { "errors", featureError.CustomErrors } }
};
return TypedResults.BadRequest(problemDetails);
} Not as cool as before... but at least I have the problemdetails model in OpenApi EDIT: but now, I m loosing the correct StatusCode.... grrr, so not good. => worst. |
Right. If there is some fixed set of status codes for |
I will try this way... because I have the current status code in my IfeatureError. I was thinking that the .Problem() will cover all my needs but no. My Api will return ProblemDetails for all possible err status code... sad I cannot document that easily. |
linked to that #52424 |
Perhaps what you want is to add a I added a ProblemResponseTransformer to my TransformerGallery project to demonstrate how to do this. It adds a 4XX response to every operation -- it was pretty straightforward to develop. I hope this is helpful. |
Thanks @mikekistler. Just a small detail: you missed a forward slash after Speaking of transformers, this is also a cool one that adds a security requirement to each operation based on the security policy that has been set: |
@mikekistler, this looks great! Now, I'm unsure whether to use .ProducesProblem(4xx) to detail all possible problem returns for each endpoint or to go with your transformer. I appreciate having visibility into all potential status codes—for instance, an update might return a 409 due to an "optimistic concurrency" exception etc etc. However, I wonder if providing so much detail is necessary, or if a more general approach would suffice. At the end, it's for a side project I have, and I believed that this TypedResuls.Problem() thing was the Holy Grail 😄 To enforce the result types for my endpoints and to have an OpenApi documentation that fits without any effort. |
Summary
Enhance the way we return
TypedResult
for minimal api andProblemDetails
when the system raise an error.Motivation and goals
I believe the newly added features related to this topic are great, but there is room for improvement.
In scope
Out of scope
N/A
Risks / unknowns
None
Examples
The way we can now use the following code is great:
Enriching our problem details in this manner is simply ❤
For exception handling in the case of a real exception, the ability to inject the
IProblemDetailsService
service is cool:However, I believe there is a need for more clarity regarding when we are serious about error handling and do not want to raise an exception in the case of a normal error. An exception should indicate an unplanned error.
Now that we have the TypedResults extension and a way to enforce our Minimal API to return certain types, ValidationProblem seems unnecessary because ultimately, we want to return either our normal typed result or a typed ProblemDetails result.
Something like that:
Task<Results<Created<TenantStandardResult>, ProblemHttpResult >>
Not something like that
Task<Results<Created<TenantStandardResult>, ProblemHttpResult, ValidationProblem >>
On my end, to always be able to return
ProblemDetails
in the case of "business" errors, validation errors, or exceptions, I created a new extension calledCustomTypedResults
as follows:With that, I m able to pass the result of a fluent validation (Dic) (like before with TypedResults.ValidationProblem():
CustomTypedResults.Problem()
Or pass my error interface (IFeatureError), the same way:
CustomTypedResults.Problem()
And maintain my typed API returns simple:
private async Task<Results<Created<TenantStandardResult>, ProblemHttpResult >>
Detailed design
I am unsure if this approach will be interesting for others, but I believe it simplifies the process and allows us to consistently return
ProblemDetails
without further consideration.Mainly when you don't use exception handler to trap normal errors...
I think it's not good and I prefer very much the
Either<IFeatureError,RightResult>
pattern and be able to transform aIFeatureError
toProblemDetails
.I am curious if it would be beneficial to explore this topic further or if anyone has a better approach already.
The text was updated successfully, but these errors were encountered: