When I started off as a developer, there was no distinction between the frontend and the backend code. The coupling was tight, the architecture stateful and the screens where character-mode. Form validations where done through triggers. These triggers were
written in C, which in-turn, would connect to DB. The processing logic remained in C.
Architecture is a result of product vision and selling proposition. As the vision transformed into selling services independent of the frontend, the tightly coupled layers gave way to loosely coupled independent blocks. The architecture moved to SOA and
the services were consumed by the web application built in MVC.
The validations were broken down into frontend and backend. The light-weight data-type/field length validations moved to the javascripts while the logic heavy validations and processing remained in C (server side). Triggers were replaced with services. As
developers, we made sure to replicate the frontend validations on the server side too so that our services worked independent of the frontend.
The markets evolved, the risk appetite of the consumers changed. The era of multi-year core banking transformation gave way to gradual, pick and choose, transformation. Composability took over from modularity. The products design evolved from modular services
to a set of micro-services. The architecture moved towards headlessness.
Common digital platforms now serve various access channels while drawing services from APIs exposed by different product vendors
The canvas for banking product selling broadened. The use cases were multiple, provided the API was a complete logical unit of functionality – from validation to request processing and error reporting.
Throughout these changes, the validations on the server side remained a non-negotiable, even at the cost of replicating the validations built on the client side.