Front-End Microservices
I don't think I'm quite to a place where I believe that every single page should be a separate application. That certainly seems overkill and counter productive.
But, by the same token, I think that there are some good arguments for modern sites and web applications to split their application into multiple UI projects.
The impetus behind this is "login". But, I think it could also apply to error pages, as well as perhaps to things like setup or admin areas in an application.
Breaking an application up too far runs the risk of repeating a lot of code. There are ways around this, like simply bundling shared functionality into one of more packages which you can consume via npm or nuget or whatever suits your project. But, you could still run the risk of importing way too many things for a simple project or breaking up common functionality into too many smaller libraries to manage with ease.
The middle ground is break things up into logical sites, of which there would hopefully not be too many and where the divisions can simplify code.
Login is a good example. Your login page is the gate keeper. And while it is pretty limited in functionality, incorporating one into an application, especially something like an SPA application introduces an additional layer of complication. A login page usually does not contain all of the same elements as the rest of an SPA. There is no side nav, maybe no header, and so on.
It is also one of the few pages which doesn't require authentication. And the list goes on. It is an anomaly compared to the rest of the application. And. in the process of implementing is a separate web site, you will likely be forced to address problems which will help you more consistently detect security attacks against your web site.
Put another way, to implement this so that everything works nice, you'll likely have to implement a reverse proxy. But. that simple reverse proxy can then become your gateway, not only routing requests but handling authentication centrally on the server side, sanitizing headers and ensuring that only valid, authorized requests go to the correct endpoint on the front and with valid authentication data.
It also sets you up to easily refactor your authentication model without as much need to worry about how it may impact the rest of your front end. For instance, you decide to add 2FA. You no longer need to worry about how to add yet another deviant page to your SPA which now, not only violates your general web site design language, but which also occupies a state in-between the original log-in screen and being actually logged in.
Also, since you had to go and add what is essentially an API Gateway to manage this, you could also easily redirect based on other authentication or identity based rules without worrying about how to ensure that the UI can handle it. For instance, an admin may need to be redirected to a different version of a page. Or if you're doing blue/green deployments you may want to redirect some users to a different version of the site.
Error pages are another use case. They generally aren't all that exciting, but they also tend to break the design conventions of the rest of the application. And their demands in terms components, etc... are often much lighter. So it would likely be quite sensible to redirect them to a completely different web site.
In fact, such a redirection should have a pretty cool side effect; by leaving the app domain of the original application you may also be making it a bit harder for them to inspect the state of the application at the time of the failure which might help defend against malicious attacks. By no means is this going to stop a skilled and determined attacker but it also highlights one of the problems with monolithic UIs; they are often holding onto a lot of data at any given moment which isn't directly tied to the current page.
Shifting the Login to a separate UI and handling the validation server side before it ever hits the page has the biggest advantage here since it takes a lot of the stored authentication data out of the client side entirely. And, if validating and sanitizing headers on each request you're also closing down a major vector for attacks.
But, those aren't the only types of bugs and attack vectors which exist. The more of your data and services that are exposed at any given time, the larger your attack surface. Breaking your application up where it makes sense can reduce the number of services and the amount of data any one part of the application may be caching at any given moment.
I don't feel it makes sense to break up applications too far. But, ultimately it will depend on a number of factors. If each screen in your application is mind-bogglingly complicated and is worked on by a different team, then it may make sense to make every page a separate application sharing some common libraries and controls. But generally speaking, it still makes a lot of sense to break up along certain boundaries like authentication, errors and your typical application workflows.
And, I think it almost forces the use of an API Gateway type service which I think that honestly, every application should be implementing anyway as almost every web application has at least 2 services (front end and back end) hosted in different frameworks. Not planning for this leaves people at the mercy of things like nginx or whatever your cloud provider offers. And generally leaves you with a gimped solution with authentication handled natively and routing handled by a 3rd party.
Comments
Post a Comment