As the needs of web apps have grown, I have found myself writing more and more API driven web applications. I use frameworks like AngularJS to build rich web clients that communicate with these APIs. Currently I am using PHP (Lumen or Laravel) for the server side / API.
The problem is, I find myself repeating business logic between the client and the server side often.
When I say business logic I mean rules like the following for an order form:
- You can buy X if you buy Y.
- You cannot buy Y if you have Z.
- If you buy 10 of these you get 10% off.
- Height x Width x Depth x Cost = Final Cost.
- Height must be between 10 and 20 if your width is greater than 5.
- Etc etc.
To make this app both responsive and fast, the logic for calculations (along with other business logic) is being done on the client side. Since we shouldn't trust the client, I then re-verify those numbers on the server side. This logic can get pretty complex and writing this complex logic in both places feels dangerous.
I have three solutions in mind:
Make everything that require business logic make an ajax call to the API. All the business logic would live in one place and can be tested once. This could be slow since the client would have to wait for each and every change they make to the order form to get updated values and results. Having a very fast API would help with this. The main downside is that this may not work well when users are on poor connections (mobile devices).
Write the business logic on the client side AND on the server side. The client gets instant feedback as they make changes on the form, and we validate all data once they submit on the server. The downside here is that we have to duplicate all the business logic, and test both sides. This is certainly more work and would make future work fragile.
Trust the client!?! Write all the business logic on the client side and assume they didn't tamper with the data. In my current scenario I am working on a quote builder which would always get reviewed by human so maybe this is actually ok.
Honestly, I am not happy about any of the solutions which is why I am reaching out to the community for advice. I would love to hear your opinions or approaches to this problem!