Single Application vs Microservices
At the start, we recommend that you build a single application. A monolithic codebase that handles everything is generally faster to develop and easier to maintain than a complex network of microservices connected by hubs to a public interface. As long as you keep the code modular, you can always break out major functions into separate codebases later as you scale up.
Page-Driven Design vs API-Driven Design
Page-driven design is robust. It uses simple GET links and POST forms for that sturdy but somewhat choppy page-to-page user experience.
API-driven design is elegant. It uses client-side scripting to separate the front-end interface from a back-end data API, for a dynamic but somewhat unreliable action-to-action user experience.
Both design structures have their place and overlap in some ratio. At the start, we recommend that you bias towards page-driven design for its absolute reliability and development speed.
Model-View-Controller Paradigm and Intermediate/Utility Layers
MVC code organization standards recommend that you separate your views (layout/style) from your controllers (HTTP request/response handlers) and your models (conceptual black boxes dealing with data). This 3-layer distinction is useful, but insufficient.
One of the most common mistakes is to stuff your HTTP controllers with business logic that will have to be repeated across other pages on the website and the API endpoints that service your mobile app (ex. complex sign-up process code getting copy/pasted 3 times is a definite mistake). The solution is to package that complex code block into an intermediate class that can be more elegantly called upon from the multiple HTTP controllers that need it.
Separation of Concerns: Lakes vs Rivers
Maintainable code is where you expect it (ex. all authentication calls start from the Auth class). If you make a change to a central class, you expect the changes to apply to all related cases (ex. increasing the base transaction fee should apply that increase across all transactions without any hard-coded exceptions). Central classes are excellent for pooling code into a single file until you have a better understanding of how and whether to split it up the right way later (ex. start with a BusinessConfiguration class instead of BusinessSummertimeTransactionConfiguration).
Handling Errors and Partial Successes
In error handling, the ultimate goal is to cover all unexpected possibilities with error detection, elegant failure, and ease of debugging.