What we usually have at work is an API that has a single consumer, usually a SPA web frontend, which is built by the guy sitting next to you.
I completely see the need for authentication and authorization.
What tends to happen in the controller methods though is a little insane to me. Basically the request is absolutely not to be trusted. Every Controller method start with "check this, check that, make sure its not this, make sure this is true" and give out "correct" response codes and messages. null check null check null check.
Lets say we have an Update Offer post endpoint. So the Request is some kind of offer with an Id and a list of Items with corresponding OfferIds. The only ones who even know the endpoints and requests are our employees.
- First I validate its the right request, makes sense.
- Then I validate whether the Offer actually exists.
- Then I validate whether the items actually exist.
- Then I validate whether this offer belongs to the user.
- then I validate whether these items belong to that offer.
- top all of that off with excessive null checks
- if its the create offer endpoint, check that the request offer doesn't have an id
These are all just examples. Please do not focus in on how I could remove the Id from the CreateOffer request. Or similar.
None of these are that bad by themselves. Its just a lot of checking and you end up with 30 lines of checks and validation followed by 2 lines of actual code in every single request handler.
I feel like those best practices are for either public APIs or APIs with a lot of consumers.
To me this code has no purpose. Its written to give someone who puts complete gibberish into our endpoints as good of an experience as possible. But the only one who could do so is my coworker.
Lets say 2 people are working on the backend API. One on the actual request endpoints and another one on the database repository layer.
So I am the repository developer, its my job to create a OfferRepository.Update() method that takes an offer object and persists it to the database. My colleague handles business logic in the endpoints and then calls into my repository to make sure it gets persisted.
Do I as the repository developer have to do all the same checks again? Throw custom exceptions and make up status codes? I think most people would agree that, that would be stupid. When does it end? Do I stop trusting myself within my own method and do the checks again for good measure halfway through?
So why is Request => endpoint any different than endpoint => repository? An exception is not a big deal. Either the frontend guy or the request guy is just gonna tell you "hey man I called ur code, it crashed. How can we fix it?"
I think all of this comes from a totally good place. People google and try to follow what way more experienced people do. To me this code adds nothing to the project. It doesn't solve any problem or task. Its essentially "look you can put everything in here and get a nice response. Aren't I the cleanest coder?"
You cannot stop other developers from crashing your code, if they actually try. I need two lines of code to crash microsofts implementation of the division operator.