❔ Where to put this logic ?
Hi folks,
I have a very simple project that have 3 layers : Api, Domain and Infrastructure
I have a mongo collection which contain users.
I want to implement a very simple feature. Delete a user by its Id.
I have two options :
1. In the domain I first try to get a user by the given Id. If it's there I delete it, if not I throw a NotFoundException. This exception is then catched in the API layer to return a Not Found Status code. The disadvantage of this approach is that I am doing 2 access to the database.
2. I simply try to delete the user in the infrastructure, then I use the WriteResult of mongo. And there are here two sub-options:
i. Either In the infrastructure, I check that the nbRemoved is not 0. If it is the case, the infrastructure throw a NotFoundExceptionthat will be catched in the API and mapped to Not Found status code. In this case, I think the disadvantage is that the domain does not contain much, it's a logic that should be in the domain but that's put in the infrastructure.
ii Or the infrastructure will just return nbRemoved (and not the whole WriteResult) and thus the domain checks if it's 0 and throw the exception
I am trying to choose between 1. and 2.i and 2.ii. Any help ?
17 Replies
1) Don't do that. Exception driven workflows aren't a good idea. Have your service return a
bool
representing if it deleted the entity or not instead.
I would still return a 2xx to the users. Delete operations should be idempotent in anything REST-adjacent.you mean from the infrastructure I return a bool to the domain which will return that bool to the API and depending on its value it will eventually return 404 ?
(assuming I am still doing the 404 here)
That's what I'd do.
(but without the 404)
but if you're not doing 404 why would you return a bool ?
the result will be 200 anyway
whether you've found the object or not
You can return 200 true or 200 false.
(Or even a custom message or something, depending on how you're approaching it.)
okay, I appreciate the idea. Here the operation have only two alternatives : it's removed or not. How about some logic that would result in more ?
Somehting like a conflict, a not found, and an ok for example
a bool is not sufficient
how would you do that ?
Then you'd have a proper body returned with a status (or error) code (enum proper to your application) and a descriptions.
But a conflict is a good reason to return a non 2xx
Not Found, you can either return 204, or 404, depending on your strategy.
It's just that the delete operation itself in rest should be idempotent, just like the PUT generally is too.
by the enum here you mean the infrastructure will return an enum represeting the different alternatives instead of the bool right ?
I was talking at the API level. Underneath it depends how it is.
Not Found would be raised through a null or a false, depending if it's a get, a put or a delete.
For the conflict, it depends on how first encounter the error.
If you can detect the conflict, I would have that layer return an
OperationResult
struct or something instead. If you can't (for example, if it was EF and it was a concurrency token that failed) and it's already an exception, I'd catch it in the service and return an OperationResult
to the Controller and the controller would convert that to something relevant for the endpoint.
Some people would disagree with that approach since there are many ways to skin a cat.okay, thanks it helps a lot.
Feel free to shop around for a solution too if you want to get more opinions on the topic!
yup yup, I will
meanwhile if you have a resource (blog post, video, whatever) on proper error handling (not through exceptions) feel free to suggest :p
I don't sadly. I can try finding something.
Okay, I would be grateful 🙏
https://youssefsellami.com/exceptions_vs_result_object/
I browsed it quick and it feels on point.
okay thanks 😊
Looks like nothing has happened here. I will mark this as stale and this post will be archived until there is new activity.