C
C#2y ago
LazyGuard

❔ 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
Yawnder
Yawnder2y ago
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.
LazyGuard
LazyGuardOP2y ago
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)
Yawnder
Yawnder2y ago
That's what I'd do. (but without the 404)
LazyGuard
LazyGuardOP2y ago
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
Yawnder
Yawnder2y ago
You can return 200 true or 200 false. (Or even a custom message or something, depending on how you're approaching it.)
LazyGuard
LazyGuardOP2y ago
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 ?
Yawnder
Yawnder2y ago
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.
LazyGuard
LazyGuardOP2y ago
by the enum here you mean the infrastructure will return an enum represeting the different alternatives instead of the bool right ?
Yawnder
Yawnder2y ago
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.
LazyGuard
LazyGuardOP2y ago
okay, thanks it helps a lot.
Yawnder
Yawnder2y ago
Feel free to shop around for a solution too if you want to get more opinions on the topic!
LazyGuard
LazyGuardOP2y ago
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
Yawnder
Yawnder2y ago
I don't sadly. I can try finding something.
LazyGuard
LazyGuardOP2y ago
Okay, I would be grateful 🙏
Yawnder
Yawnder2y ago
https://youssefsellami.com/exceptions_vs_result_object/ I browsed it quick and it feels on point.
LazyGuard
LazyGuardOP2y ago
okay thanks 😊
Accord
Accord2y ago
Looks like nothing has happened here. I will mark this as stale and this post will be archived until there is new activity.

Did you find this page helpful?