Plus One For Micro-UIs
Today the question was asked; how do we unify around a single UI paradigm when we have 2 separate disparate ecosystems on different UI frameworks.
My first suggestion was Micro-UIs inside of iframes in the existing application. But, then, apparently the first such shared control was a side nav bar. That, unfortunately, is part of the main "container" of the application.
So, now the role is reversed. The best option would be to put our existing app inside of an iframe of a new "container" app.
But, the login is also part of the "container" and already done in the existing SPA. Which means that it cannot be embedded in an iframe in the theoretical new app. It would need to be redone in the new framework... or served up separately.
Well, now we're in a bit of a pickle. UI rewrites are long and arduous things. But, they tend to be that way specifically because they also tend to be all or nothing affairs and there are so many layers and screens to deal with.
What I'm about to suggest is not really a solution to an existing project. It would require a lot of luck that everything would just work. BUT, an application designed with this in mind would have a lot more flexibility.
And that suggestion is 3 main Micro-UI "layers" with the lowest layer potentially being many Micro-UIs. And all of this relies on a concept I built out around my reverse proxy solution.
You have one or more endpoints meant to handle unauthenticated requests. These route to the login screen and the login backend logic which is handled directly or indirectly by the Reverse-Proxy/Api Gateway. This way the Login logic can be stripped out in a small, lightweight, dedicated Micro-UI.
Once the Gateway detects that an authenticated user is present, it instead routes to the "Container" layer. A top level UI containing functionality like navigation, alerting, etc... which may or may not be written in the same framework as the UI and/or the next layer down.
And that next layer down is the documentation/presentation layer. This is responsible for the "meat" of the navigation pages. These would most likely be served up in iframes and each page could either be individual pages from a single application or could be served from one-to-many MicroUIs.
Where necessary, it is possible to send messages between an iframe and the host container (and back). So long as both are aware and built to do so. This would allow interactions between the two into that common wrapper layer for notifications/toasts, etc...
From my perspective the advantages here are clear... firstly you can replace any one layer independent of the others. As long as the replacement is compliant with what it is replacing, the other layers will be unaware. The next part is that the main part of the application can now be transitioned iteratively. In fact, you could even have a toggle that says something like "Preview New UI" which sets a header and instructs the Proxy to route differently based on that header value. In which case, until the new UI is done and fully vetted, a user could opt into which UI they work with.
Something akin to this is undoubtedly how companies like Microsoft handle whether you're served up a new or old Outlook experience in the web application. You still go to the same URL, but based on some header or account configuration value, you're routed to a different experience.
And there is no reason why you couldn't leverage the same sort of concept with your MicroUIs.
As I said though... it isn't AS realistic for an existing project. In those cases there could still be a lot of up front code required to support the architectural shift. But, it highlights my point that good software engineering requires that you plan for the future. This architecture wouldn't complicate the original release all that much. Especially not compared to headaches it saves you when you finally discover that you need or want a framework rewrite.
It also applies on the backend BTW. In a prior job we were using an API Gateway concept of sorts to rewrite our OData v3 requests and serve them to our OData v4 endpoints. This gave us a much longer runway to deal with the final transition.
It meant that we could start with the back end rewrite and the client's could continue talking to the old services. As we approached API completion we could advertise that those old endpoints were being deprecated and then sunset them only after the new APIs were completely done and tested and sufficient notice had been given. We could even throw reporting on the API Gateway to determine what the usage levels of the old vs. new endpoints were so that we could make informed decisions around whether or not we had high volumes or traffic left on the old endpoint.
The point is, with both UI and backends, good architecture is good architecture. Period. And good architecture is generally resilient and scalable. Those are things Microservices and MicroUIs can do well and which Monoliths do not.
Comments
Post a Comment