Building scalable frontends

Scaling frontends is hard, actually scaling all codebases is hard, frontends just happen to be particularly visible and have a tighter feedback loop and a higher rate of change. As with all codebases, it is in principle possible to scale development through standards and integration processes, but these are a poor substitute for communication. Once development moves beyond the scope of a single team, either progress slows to take into account of different processes or implementations drift away from each other over time. Teams need to find a way to operate independently towards a goal.

As with all problems with computer science, a potential solution comes in the form of a layer of abstraction. Backend codebases introduce abstraction in various ways to allow for a region of functionality to be logically separated. Abstraction layers take many forms: classes, interfaces, modules, libraries, microservices and subsystems each offering benefits and compromises. Units of re-use become used for subdivision of labour and comprehension within an organisation.

Most options for abstraction and organisation are available in frontend code, it’s code so why wouldn’t they be. However, recently some of the more architectural patterns such as microservices have begun to be explored.

Micro frontends

In an attempt to simplify and separate codebases in a similar way to microservices, micro frontends split the UI into separate sections that can be delivered and updated independently. However, the benefits are tempered by the need for increased integration testing.

Microservice frontend team structure

A traditional frontend would look like the diagram above, with the frontend implementation cutting across multiple microservices. This architecture tends to result in either there being a frontend team which can create a bottleneck or multiple teams each making alterations in a single frontend codebase, possible but logistically complex. Another side effect of this arrangement is that the frontend tends to become an orchestration point for the whole system, gradually absorbing functionality from the microservices, causing them to become anaemic database as a service. Everything comes full circle, and we now have a monolith in the frontend.

Micro frontends align user interface components with supporting microservices allowing a single team to own development end to end.

Aligned team structure

The separate user interface components need to be composed to create the whole user interface. There are multiple methods for composition typically using some form of container with on the server or in the client. Care must be taken to constrain interaction between components to reduce coupling, clearly defined interfaces, and events ease adoption.

Each of the teams has a full build pipeline for their component with a final integration step to create the complete application.

Design systems can be used across all of the components to ensure visual consistency between the components. Design systems can be developed by a central team or in a more distributed manner, the key to success is governance of changes and stakeholder management. Versioning and backwards compatibility also have a large part to play in adoption.

Increasing scale

Large organisations may need to scale beyond the scope of single applications, and frequently need to create a seamless user experience across multiple subdomains.

Interacting subdomains

Micro frontends will continue to work effectively within a subdomain, but across the whole domain, the integration overhead will quickly become unmanageable.

To work across multiple subdomains, other patterns must be used. Two key elements are required to deliver a consistent user experience across all of the subdomains:

  • Single sign-on allows the user experience to be personalised across the whole domain
  • A design system ensures visual consistency across all of the subdomains

If the two elements above are in place, it becomes relatively simple to integrate into the display with links between the subdomains being created in the same way they would be if the links were to an external site.

Background integration with APIs can be used to share information between subdomains, restful APIs that contain links to content help decouple the subdomains limiting the amount of data that needs to be shared for them to interoperate.

Events streams are also useful mechanisms to share data between subdomains, by definition events happened in the past and are immutable so they can be copied across the organisation domain freely. However, care needs to be taken interpreting events emitted by other subdomains.

If input is required from a user, they should be directed via a link to the subdomain that owns the data and process, avoiding issues with eventual consistency and also implementation of business process in multiple domains. Some components such as navigation may need to be shared across the entire domain with elements of configuration for local scope.

Integration via links also has the advantage that alternate technologies can be used across the domain, not requiring a single framework to be adopted.

In practice

An excellent example of an integrated user interface at this scale is Office 365, identity, design, and some navigation elements are shared across all of the products in Office 365. Still, they exist on multiple domains, e.g. office.com, sharepoint.com etc. Background integration via graph API’s allows the user interfaces to pull resources from other products, e.g. office.com pulls recent documents from SharePoint to be able to have personalised links on the Office homepage.

Conclusion

Caution should be used implementing unified user interfaces, use of a single framework can cause issues over time. To be able to unify multiple domains, it can often be simpler to rely on more straightforward techniques such as a single identity and design system, tightly scoping individual technology choices to a particular subdomain.

Jumping into the FHIR - type systems and objects

We have been doing a deep-dive on FHIR implementations and tooling following our initial FHIR investigation. A critical area of investigation for any system, particularly a large distributed system with many clients and peers that need longevity and guided evolution is its type system. Use of a strict type system can have many benefits - interoperability, governance, data quality, security, performance, developer experience, reduced component complexity and the ability to evolve services with confidence

Integrating with Events

The San Digital team has worked with numerous organisations in both the public and private sectors to transform their applications architecture into a flexible and business-focused model. Working with events at scale is key to maintaining individual teams' agility.

The process of building a mobile app

The team at San Digital has extensive experience developing apps for mobile devices, smartwatches, and smart TVs; using native and hybrid technologies (and everything in-between!) including using Rust for complex comms.

Low friction development environments

While setting up a sample project from an unnamed large vendor the other week I was disappointed by having to read large amounts of documentation and run various bits of script to install dependencies and set up infrastructure. We live in a world that has tools old (Make) and new (Docker) that can be combined to make onboarding engineers low or zero friction.

Cloud-native FHIR platforms

Continuing our series of posts on web protocols, we have been investigating more specialist protocols, in this case, "FHIR". We have produced a document based on our research, investigations and experience.

Team Structures

Multiple team structures can work to deliver software projects. There is no real one size fits all, however, there are common components that can be seen across different structures. At San Digital we believe that Engineer-led teams deliver great results for short duration high-impact projects.

Rules of the Road

This is called rules of the road but they aren't rules they're more guidelines, so they're rules until there is a good reason to ignore them.

Estimating and delivering defined outcomes

Recently there has been a shift away from time and materials projects towards defined outcomes, driven by various legislative changes, specifically IR35, but also cost control in the procurement function of larger organisations.

The San Digital Stack

San Digital has been designed as a remote first business from inception, on the assumption that it's easier to add offices later if they are necessary in an agile way. To work in collaborative way completely remotely takes a carefully thought out set of tools. Some of the ones that we use are really standard and some are a little more interesting.

Test driven design, or planning driven development

Design processes in most business software development resemble peer review or crowd-sourcing. A putative design is presented to peers, who will do their best to find problems while the originator of the design defends it against these challenges. Ideally, where they are demonstrated incorrect or incomplete the process will iterate and an updated design produced and defended.

A human view of computer vision at scale

Computers analysing and acting on what they see is not science fiction or even a new concept, it has been a reality of humankind's drive towards hyper-efficiency since around the time I was born.

Building scalable frontends

Scaling frontends is hard, actually scaling all codebases is hard, frontends just happen to be particularly visible and have a tighter feedback loop and a higher rate of change. As with all codebases, it is in principle possible to scale development through standards and integration processes, but these are a poor substitute for communication. Once development moves beyond the scope of a single team, either progress slows to take into account of different processes or implementations drift away from each other over time. Teams need to find a way to operate independently towards a goal.

Cross platform native mobile development with Rust

San Digital have extensive experience of mobile development and the use of Android as an embedded operating system. We treated android as a deployment target target for Rust firmware as well as writing our intricate real time communications component for both iOS and Android. This approach has advantages, you can maintain a single code base for a complicated communications layer, while also taking advantage of the full native capabilities of each platform

The evolution of web service protocols pt 2

At San Digital, some of us have been building things for people since the dawn of the web. Our historical perspective helps inform us about technological culture and trends today, almost compensating for the creaking knees.

The evolution of web service protocols pt 1

At San Digital, some of us have been building things for people since the dawn of the web. Our historical perspective helps inform us about technological culture and trends today, almost compensating for the creaking knees.