"Business logic should never be in the frontend."
I once overheard that conversation at a coworking space where a technical cofounder was explaining the work to the other founder. I didn't know that founder well enough at the time to tell him how wrong his cofounder was.
Let's get some background out of the way. I hate frontend web development. I hate it deep in my bones. I hate everything involved in it, from the dependency nightmare in the Javascript ecosystem to visuals being managed in HTML/CSS rather than code. I once went off on my manager about our company's increased investment in Javascript technologies rather than focusing on "real" technology.
When I think about it, things are less awful than when I first encountered frontend. Back then, maintaining IE6 was still a thing. Things are way better now, but I still have a lot of lingering hate.
I'm not the only developer with those feelings (though the intensity of my feelings may be above average). "Business logic should never be in the frontend" guy definitely has those feelings.
The problem with feelings is that we can't just have them. We need to justify them. We need to have a reason for feeling the way we do so that we can still sound intelligent and logical to other people.
I too once believed business logic shouldn't be in the frontend. You can't trust the output of that logic. Frontend code can be manipulated in the browser. Web requests can be intercepted and replayed. All you really need is the auth token and you can send anything to the server.
Not only that, the frontend code is all in the browser. If you put proprietary business logic there, then anyone can copy it!
All of that sounds sensible. All of that sounds correct. Thing is, it's only correct to a point.
Should an e-commerce site handle payments in the browser? Probably not. But not all logic is at the level of payments. I handle a lot of calculations for our platform on the frontend such as generating amortization tables. Could a user change things to make the tables wrong? Sure. Those users could also do the same thing in Excel where they can... make the numbers whatever they want.
Speaking of Excel. I got my formulas from my co-founder's Excel templates. I'm sure plenty of other accountants have those same formulas. I bet hundreds, if not thousands, of companies have written code to generate amortization tables. Trade secrets this code is not.
Why put it on the frontend though?
First is user performance. All network requests have some amount of overhead. On top of that, web servers need to go to the database to get information so we're not just waiting on the round trip from browser to web server, we are also waiting on round trips from web server to database (though the latter should be much faster). Contrast this with a single page application with all the information it needs already loaded. It can just run the calculations. Even if the code performs like garbage (hello, mine is O(n^3)), it will likely return to the user well before a web request could return "hello world".
That also leads to potentially better scaling if you don't need to validate the output since that's calculation that doesn't have to be handled by your infrastructure. You do have the option validate the ouput by duplicating the logic server side when the user triggers a save action (compared to being able to re-run calculations on keystroke with the frontend logic). That gives you the performance for the user while also ensuring the output is pristine. The risk of duplicated code can be mitigated with tests so you're really just paying the cost of extra work in return for a better user experience.
The analysis of trade offs and decision making in handling things on the frontend, backend, or both, has to be done pragmatically. The system needs to be looked at as a whole rather than in pieces. It doesn't necessarily need to all be done by one person, but it should be done by a single team.
Why would I recommend that? Why can't you just have separate frontend/backend teams and just have the leads meet regularly?
You could do that. It makes perfect logical sense. There are going to be a number of problems that surface that I highly doubt your organization properly mitigates.
1) The people doing the work are not involved in decisions.
If only the leads meet to make decisions, especially deep technical ones, then the engineers doing the work will not understand what goes into making those decisions. They won't understand what alternatives were ruled out. They won't understand why certain things are a concern and why certain things are not. You are basically treating them as code monkeys rather than engineers. This will greatly reduce their productivity. On the one hand you have engineers who will spin their wheels worrying about things that were discussed, but not communicated well. On the other you will have engineers blindly implementing what you told them, but you almost certainly forgot to account for some edge cases and did not give those engineers the tools necessary to work it through themselves. In either case, the lead engineer will likely be peppered with questions every few minutes and get no work done themselves.
2) Cross team coordination is really awkward.
I've lost count of how many times I've seen a change need to be made by one team, but they're waiting on another team to make a coordinating change. Adding a new parameter to an endpoint should be quick and easy, but can take hours (if not days) when split among two teams. Are there technologies and processes you can implement to mitigate that? Sure. Yet, it is way easier, cheaper, and faster to just give one team the tools they need to implement a feature completely.
3) Incentives are not always aligned.
This point is 100% an organizational issue that I have never seen resolved. I have seen executives and managers *say* it was solved in their org when reality did not match up with their words. Whenever you have more than one team, each of those teams is going to have different incentives. Those incentives may be performance reviews. Those incentives may be what they in particular find interesting to work on. Those incentives may also be in a position to defer blame just in case. It is way easier to create a mindset of "we rise and fall together" with everyone in a single team than it is across multiple teams. That mindset keeps people focused.
One of the things that has been extremely consistent across all the teams I have worked with is that the teams that have been closest to being independant and having everything they need to build and release software have been more productive than teams that were built in silos. Despite me creating a finite list above, the symptoms in which those problems manifest are extremely varied and small. Something as innocuous as someone asking to always be consulted on a particular type of decision. Or someone finding something else to do while they wait on another team. There's thousands of ways those problems can manifest and the only way I've seen that can address all of them is to make your team full stack.