NAB-X: a microservice-like approach in the application experience space

At NAB, microservices have been adopted broadly, and are a growing and evolving ecosystem. This has meant that data is unlocked to build new customer experiences, and duplication of server-side build effort across channels has been reduced.

This model also means that ‘Federated Delivery’ is possible, in that domain owners can release new versions of microservice functionality on an ongoing basis for platforms to consume.

While this provided a way forward on the server-side, we still had no roadmap for solving the same types of problems that arise from maintaining multiple monolithic frontend stacks.

This article outlines the NAB-X platform used for federated delivery of frontend capabilities at NAB.

Problems we aimed to solve

The following issues were targeted as key areas that needed to be addressed.

  1. Duplicated build effort across platforms and channels for the same feature
  2. Delivery bottlenecks in platform teams servicing multiple product domains
  3. UI and Accessibility inconsistency across channel platforms
  4. High risk monolithic frontend deployments

Taking each of these problems into account, we realised that decomposing our monolithic frontends into micro-frontends and allowing product domains to become more directly involved in delivery would be worth exploring.

Micro-frontends are similar in concept to micro-services, in that they are discretely deploy-able shared capabilities, however they deliver this concept to frontend user experience. Some background reading: https://micro-frontends.org/ · https://martinfowler.com/articles/micro-frontends.html

Monolith to Micro-frontend federation

New challenges

While this strategy appeared promising, there were also some new challenges to consider.

1. We needed to provide guardrails and patterns for teams to follow that would ensure a cohesive user experience, and compliant deployments.

2. We needed to provide tools to our teams to accelerate delivery of features, by removing the need to reinvent how to do basic, but time consuming, things such as authentication, structured logging and tracing, hosting pattern design and config management.

3. We needed to build a community around the tools and patterns in order to capitalise on the extensive cloud training that NAB had invested in, and the wealth of engineering experience that existed distributed across many teams around the organisation.

There were performance, integration and operating model aspects to be considered.

Prototype and socialise

There was enough interest in the micro-frontend concept to obtain executive sponsorship to prototype some key areas of interest and possible micro-frontend patterns. We ultimately settled on webcomponents as being the most viable approach for NAB.

Key drivers for this were:

1. Open, standards based and portable client-side integration.

2. Federated frontend hosting involved minimal resources.

3. No complex multi-domain concerns.

4. Clear integration boundary.

As we started to show various teams what was possible there was a high degree of interest, however it became clear that we would need to provide some boilerplate/templating in order to make it simpler to bootstrap new micro-frontends.

We also started to see that we would need some common standards and patterns to avoid fragmentation and ensure interoperability.

What do you mean ‘it is already in prod’?!

The NAB-X project was formed to provide the tools, guidance and coordination we would need to be successful at scale.

The NAB-X Micro-frontend approach

The key standards used are part of the WebComponents spec:

  • Custom Elements — used as the container of each miniapp
  • ShadowDOM — used to isolate styling of a given miniapp
  • HTML Templates — reusable templates used by the above

Read: https://developer.mozilla.org/en-US/docs/Web/Web_Components

Key Features and Principles

1. Discrete deployable applications, owned and operated by the teams that build them.

2. Insulation of miniapp frontends from backend api changes or platform differences.

3. Syndication of miniapps into multiple host applications regardless of miniapp hosting location.

4. Compatibility with ‘classic’ platforms, and with future frameworks.

5. Observability of the miniapp runtimes across host apps and clusters.

6. Versioning, with the ability to run multiple versions, allowing hosts apps to control adoption, or accept all updates.

7. Externalisation of authentication, authorisation and session management.

8. Reusability of miniapps across platforms, including UI consistency.

High level delivery approach used in NAB-X patterns

By using a simple platform agnostic tool such as Docker, we are able to easily evolve the hosting strategy over time, and not be limited to specific cloud providers.

Frontend
While we aim towards using pure web standard based engineering patterns, we currently make use of React within most Miniapp webcomponents. The exception is 3rd party integrations, which can also be wrapped in a Miniapp in order to be a part of the ecosystem.

Prototypes that use Vue and other frameworks have shown that we have an approach that can evolve over time with multiple generations of miniapps interacting with each other regardless of underlying technology.

For the webcomponent wrapper, we make use of Lit-Element from the polymer project which gives us a lightweight webcomponent interface with lifecycle management.

https://lit-element.polymer-project.org

Frontend code is hosted in small nginx docker containers allowing us to inject configuration at runtime, and keeping the door open to server-side rendering.

Webcomponent Custom Element and Shadow DOM of a Miniapp

Backend
Each Miniapp frontend generally has a paired BFF (backend-for-frontend) that is based on Apollo GraphQL (https://www.apollographql.com/). The BFF is deliberately tightly coupled to the Miniapp frontend and not shared at runtime. This allows teams building miniapps to optimise their backend to their specific frontend requirements, knowing that they are not affecting any other systems.

Each miniapp git repo consists of both the frontend and backend code. This is templated out for each new Miniapp via a Yeoman generator that provides a working starting point app, as well as integration with nab pipeline tools to deliver the miniapp in a compliant manner.

BFF code is hosted in Express Docker containers also fronted by nginx.

GraphQL Playground served from a Miniapp in development

Downstream services
The microservices downstream of the GraphQL BFF, are outside of the scope of NAB-X, however we have baked in api gateway token strategies based on the NAB Microservices ecosystem.

This allows teams to easily integrate with microservices without having to start from scratch.

A BFF could be your BFF

We can also encapsulate context specific differences such as needing to route api calls via different network paths based on where a miniapp is used.

GraphQL advantages:

1. We can call multiple downstream rest apis in parallel and/or chained, and stitch the responses together reducing the number of rest calls from the frontend.

2. We can query for just the fields we need for the frontend. Some general-purpose rest apis return large datasets, and if we need only a couple of fields, we can save on bandwidth.

Mobile user experience in particular benefits from this.

A basic GraphQL REST Datasource class in Typescript

Are you sure we use Comic-Sans font here?

Having the GEL defined is useful, but more useful is an implementation of the GEL that is easily consumable by frontend engineers, and has the required Accessibility standards baked in.

For NAB-X miniapps, a React component library is maintained that implements the NAB GEL and has the appropriate oversight that helps deliver experiences that are accessible to all customers and bankers.

Miniapp teams still need to ensure they perform the appropriate subjective testing of their miniapps, but this raises the bar in terms of baseline accessibility, and UI consistency.

I’ve deployed my miniapp — now what?

The supplied security hardened infrastructure code and pipelines mean that miniapps are deployed using a standard model, which ensures that the way they are integrated into Shells is consistent. This typically involves configuration/code to load the miniapp webcomponent into the Shell.

Roles and responsibilities

Platform Shell teams are ultimately responsible for the channel they represent, and so we need clear contracts for miniapps to adhere to in order to be accepted and surfaced. Conversely, Shell teams do not necessarily have the knowledge required to perform in-depth functional testing of a given miniapp.

This means:

1. Non-functional stage gates are handled in a shared CI pipeline pattern in order for miniapps to be certified and added to the catalogue of available miniapps.

2. Miniapps teams are responsible for functional testing of the Miniapps they maintain, and also for any subjective shell integration testing.

3. Shell teams rely on health-check events emitted by miniapps to understand whether a given miniapp is working as expected in their shell.

4. Agreements such as SLAs and engagement processes between shell teams and miniapp teams need to be put in place early.

The team that maintains the nab-x tools endeavours to facilitate these engagements, by providing related sdk functionality, as well as documented guidance for teams adopting Federated delivery.

Migration pathways

This is something the NAB-X team are very conscious of, and so a reference shell that is optimised for miniapp delivery is being promoted to platform teams as the next stage of evolution.

The intent is that this shell will surface fragments of the existing platform via specialised miniapps for that purpose, and all new/change work will involve building/porting features as native miniapps.

At the appropriate point in time, the remainder of the miniapps are targeted for a final conversion effort, and the legacy platform is decommissioned.

What about Mobile?

For NAB-X Native we are taking a two-pronged approach.

1. For low volume miniapps that we want to reuse on mobile, we use a webview to surface the responsive web miniapp. To make this work, we provide a webview shell as part of the miniapp generator. There are corresponding webview miniapp capabilities built into the native apps.

2. For more important features, we are implementing a ReactNative UI capability as part of the generator, alongside a ReactNative Shell implementation baked into the Native app. This means that we can share non-ui miniapp code, the BFF, and provide a mobile targeted user experience as part of the same miniapp codebase.

Miniapp Monorepo

Federated Delivery Model

A domain team can build and deploy a miniapp into their own nab-x based hosting environment without involvement from platform teams.

Once a miniapp has passed all the standard compliance and integration tests, it can be activated in multiple platforms. This may either be via code or config depending on the platform shell. The nab-x team are working on a future state shell that will standardise this and optimise for delivery of tailored miniapps.

Tailoring of user experience

In addition to this, we plan to allow users to set preferences that will control which miniapps they see, and as an extension move towards ML based tailoring that will adapt to user behaviour.

What’s next?

There are two paths to contribution:

1. Join NAB to help build the NAB-X platform.

2. Work with us as a 3rd party to build miniapps for us to integrate.

The second path still requires a bit of work on our part. We are aiming to opensource the following tools to help you build and test miniapps.

1. nab-x miniapp generator: creates the scaffolding for new miniapps.

2. nab-x sdk: the toolchain used to perform common actions and integrate with shells.

3. the nab GEL React component library: for consistent user experience.

4. build a dedicated hosting environment for 3rd party miniapps.

5. guides and documentation.

If you’re interested in working in technology at NAB, you can find out more here.

About the author: Andrew Vaughan is a Senior Manager Distinguished Engineer/Arch at NAB. Prior to this, he’s held senior developer roles at CBA, AMP and MLC.

Official account of NAB’s technology team. Inspiring readers to rethink bank technology and bringing to life the technology enabling change for customers.