Most of the web applications that I have seen developed in my organisation , have the following components :
JS App (from browser) -> Web server -> Service(s)/Application server(s) -> Database
Each of these components typically does the following:
JS App - The interface (UI) for users to interact with the application from their browsers, typically a single page app.
Web server - Listens to HTTP requests and constructs the response by calling various services (application servers).
Application server - Fetches data by calling a database, and other services and processes the data based on some business logic and returns a response.
Database - Stores data.
Let's say my organization runs a hotel booking website, and is planning to provide a new functionality of travel packages, think of a package as consisting of multiple bookings at multiple hotels, travel (trains, flights etc) bookings, etc., this new 'Packages' application would be made up of the following components :
PackagesFrontEnd - JS App
PackagesWebApp - Web server
PackagesService - Application server/service
PackagesDB - Database
The PackagesWebApp would communicate with the PackagesService, and various services that handle bookings for hotels, travel etc., to serve its requests. The PackagesService is pretty much a wrapper on top of the PackagesDB, containing some business logic.
My question is, why do the web and application servers need to be separate here ? in my example, what is the problem with having PackagesWebApp and PackagesService as a single thing ? I have tried asking co workers, and searching online, but could not find a convincing answer for this, heard and read the following reasons:
Separation of concerns: Separating presentation logic and business logic (Why can't this be done at a module level ? with interfaces in between the classes for the layers ? Also, a side effect of this is that people duplicate some business logic like validation for example, in both the components to 'fail fast' but this sometimes comes back to bite when a change was done in one but missed in the other)
Availability: If one component has a bug and it misbehaves, it might bring down both the components (The web app wouldn't be useable anyways if either of the servers is down, even when they are separated, so what is the additional benefit here ? And, even if there is a benefit to this, then, by extension the same thing might happen, where, a bug in the code for feature 'X' thats unrelated to features 'Y' and 'Z' brings down all of them, so why not separate them also ? where do you draw a line for this ?)
On the other hand, there are definitely some overheads that come with having multiple components, like maintaining codebases, integrating components, maintaining infrastructure resources, debugging/finding root cause for issues is more complicated. In such a situation, doesn't separation only make sense if it solves some problem thats worth taking on these additional things ?
Can someone please help me in understanding the reason why this is needed ?