Using UI Composition as an integration pattern in an autonomous services environment (Enterprise software architecture)

Introduction

With the web application platform quickly evolving, we are under a constant bombardment of new features, frameworks and techniques. Some of these, such as Web Components (Polymer), enables us to revisit ideas from the past, such as Web Mashups (2003, 2006). The underlying idea of both mashups and components, is to use small pieces of functional UI and assemble them into larger solutions / applications. As the Web Components are maturing / finishing cooking, I have an alternate (or intermediate) solution I'd like to discuss with you.

Background

Why this article?

As the amount of software we produce (and thus need to maintain) in our company increase (while shifting focus to meet the market and rotating some of our staff (consisting of about 50% contractors in some parts of the organization)), our development teams are struggling to deliver consistent quality. This is expressed in a difficulty to ensure green builds (no unit & integration test failures) and to ensure that we we augment our services in a way that are backwards compatible for our existing consumers. That is, we're not always aware of all of our consumers and which results they expect from the services (as they are written with a generic mindset, rather than considering conversation patterns (see the section on Versioning)).

Tackling these quality issues that comes with scale, we are continuously discussing, evaluating and adopting various software engineering practices. As an example, we have steered our existing software investments towards using message driven communication (using Particular's NServiceBus) for a couple of years now, discussed versioning strategies (including consumer driven contracts) and services boundaries. One challenge we have experienced with NServiceBus, however, is that the framework - and, perhaps, thinking in messaging patterns - is not common knowledge. Add to that the fact that we have yet to move to Azure (although we are close), we have limited hardware for the teams to deploy their solutions to, meaning that we tend to have multiple queues on the same hardware, causing a deployment and integration challenge.

Another challenge (but that we see as an opportunity) we are facing, is that our teams - being disparate and full of skilled individuals - enjoy the freedom that comes with their ability to design their own solutions to our business needs. That is - we would like to present a team with an issue and have them use their knowledge, experience and background to provide us with an excellent solution (rather than dictating exactly how they should solve a particular task). Stealing from Spotify's engineering culture series, we are striving towards the upper-right quadrant:



This means that our teams can potentially use different technology stacks (though we have, thus far, tried to align them somewhat to ease transition of team members between the teams).

What is UI Composition?

UI Composition is an technique where integration between two components are done through the UI layer. The most common usage of this, is for each component to expose a user interface control to the host, which is stitching the control together with other controls, forming a unified whole. Another approach, is for each component to provide UI level code that is executed within its host to perform a particular function.

What are Autonomous Services?

Definitions of Services differ depending on who is defining them, but for the remainder of this article, autonomous services are pieces of software which can be developed and deployed by a single team and which are free from temporal couplings to other services during its runtime.

"Temporal couplings"? Speak English!
A piece of software is said to have a temporal coupling to another piece, if it needs to wait for that other piece to perform some kind of function. This is very common in a Web Services-based architecture, where an end user application might call a web service (synchronously; waiting for its result) which, in turn, ends up calling another service (again, synchronously; waiting for a result).

Practical applications

Imagine a web application that embeds other web applications it its UI to fulfill a particular task. It could be a Purchasing application, for example, that includes UIs from Leads and Billing to facilitate finding the customer-to-be and register its billing address respectively. Let us further imagine that the Purchasing application is written by a team proficient in ASP.NET MVC and its Razor view engine, using JQuery on the client side, that the Leads application is written using Meteor with its Blaze view engine and that the Billing application is written using ASP.NET WebAPI with Angular as its client side framework.

By including a plain, vanilla (thus framework and browser-stack compatible) library in the web application responsible for stitching other applications together - the application host - and load small plugin-esque snippets from each web application the host is dependent on, we can successfully establish application-to-application communication while offering our end-users a guided experience through our process facilitated by the host.



The uicomposition library depicted in the schematic above, allows the host to register components and attach these components to UI elements (e.g. a button). The component will, in turn, retrieve a reference to the UI element and inject its event handler in it to facilitate activation. Once activated, the component can execute JavaScript in order to fulfill some kind of business logic, though the most likely approach will be to open a window to its web application - where it is not restricted by choices made by the host, but instead can use any server- and client side frameworks available to its developers. Communicating back to the host is done through client-side events, channeled through the uicomposition library (see host configuration snippet below).

Conceptual example of client-side event, but with a slightly different set of components (this article describes embedding read views from other applications and opening windows to edit / interact with the application).



For an example of component usage, please see the uicomposition wiki.


The uicomposition library is available through Bower (bower install uicomposition) and is hosted as open source on GitHub.


Other resources

For UI composition in a WPF based technology stack, I recommend reviewing Microsoft's Developer's Guide to Microsoft Prism Library 5.0 for WPF.

Comments

Popular posts from this blog

Auto Mapper and Record Types - will they blend?

Unit testing your Azure functions - part 2: Queues and Blobs

Testing WCF services with user credentials and binary endpoints