Since microservices emerged as a design pattern, development and product teams saw their power and flexibility, but also the challenge in rearchitecting an existing application to use the pattern.
Banks often have a mix of trusted old systems handling essential tasks, and new technologies to support modern demands such as mobile banking held together by teams and their knowledge. The traditional banking sector often runs a batch-like approach to data, processing vast amounts of data at certain times, like the end of the day, whereas microservices are an event-based architecture, responding to events, often thousands of times per second. This change, in particular, can result in a more responsive business but needs a degree of trust and responsiveness to accommodate it.
Banks understand the benefits of creating more modern systems, but what if a bank wants to experiment with that new feature customers are starting to ask for? How do they give it real-world testing without potentially breaking a system that “just works”.
This is where the concept of microservices can help. By thinking of each core component, you might need as a separate microservice. Have a new feature to try that involves payments? Then pull in a payments service that can process data to and from existing applications. Does that new feature then require KYC? Then bring in that service, slowly building a new feature, application, or company as you go, again all communicating with each other seamlessly.
In the case of Modularbank, for example, the lending solution consists of the following “microservices” (from now on, called a “module”) that customers can assemble into their feature(s):
A microservice architecture is now recognised by many industries (traditional and emerging alike) as advantageous to their technology teams as well as the business generally. Telecommunications providers use microservices to trial new products such as IoT offerings, new billing platforms, and integrations with chat applications. Healthcare uses microservices to replace expensive monolithic applications with smaller services for trialling new treatment programs and patient offerings.
With Modularbank, we have carefully followed microservices design principles. This means that when we find a better way to make a module, we can swap out microservices without upsetting the entire service.
Microservices by design are language & database agnostic.
We prefer writing all our microservices in Java with Spring working on any relational database. They use common patterns between microservices and modules, making it easier to exchange data between them. If an application has a customer-facing, or staff facing interface, then we write it in React.
Regarding server-side languages Java, Go, Node.js and Python are ideal choices. We chose Java, firstly because it was the language our developers have most experience with, but also because it is a common language in enterprise application development, and gives us access to a wide variety of useful frameworks and libraries. We chose open source tools as we love and support open source, and we didn’t want to pick anything that passed on a license fee to our users.
Each microservice of each module is containerised and scalable, so as demand grows, you can add instances of a service to cope in any of the ways you are used to with other microservices such as Mesos, Kubernetes, or our preference, OpenShift. You can also adopt hybrid cloud infrastructure, hosting services with cloud providers if possible, and also on-premise if they process sensitive information. The hybrid cloud approach applies to each service, but also the microservices of each module. For example, the payments and accounting modules hosted in different locations, but a storage microservice and an application microservice of the payments module also hosted in different locations. A potential side effect of this approach is that it also enables banks to start testing cloud-hosting without jumping straight into it by isolating a small part of their business as a test.
Communication between each module happens via messages (using RabbitMQ) and standard HTTP API calls, so again, any other service a bank or FinTech runs can also subscribe to these if needed. If you are looking for a new payments solution, but have an existing CRM with API access, then you can integrate the payments module with that.
There are some challenges with taking the modular approach. Firstly, the handling state. In a microservices-based application, it is often a challenge, but even more in the banking sector, where using something like eventual consistency is not appropriate in, for example, an account balance. We had to take a more compromising approach with data from some modules combining transactional consistency inside one module and eventual consistency between modules. We call it “pragmatic consistency”.
Secondly, monitoring. Typically you monitor one application in each environment (development, staging, production, etc.), but when using microservices, you should also monitor each service running in each environment. That’s a lot of monitoring, and while that gives you a lot of insight, it’s still something that takes time to setup. With customers that we work with, we use Kibana and set up clear correlation IDs so you can see what customer triggered what events and when throughout the application as a whole. Tied directly with the monitoring is the general infrastructure around microservices such as continuous integration and testing pipelines. It’s something that Modularbank is happy to handle, but again, don’t underestimate the initial outlay of time.
The final challenge is generally a cultural one, allowing teams a degree of autonomy in their decision making and delivery is sometimes a difficult culture shift to make.
We have found that giving each team expected deliverables is a good way to start tackling the cultural challenges. If each team is expected to deliver x bug fixes and y features per quarter, but the release cycle cadence to do that is up to them, you give them autonomy, but with guidance. With each team working on their service or component in this manner, you give your customers a product that is constantly improving.
If this all starts to sound too much for some IT teams and their managers, the best justifications we have found is that once you have completed setup, then feature and update releases are much faster. Teams are able to work on their individual features and components, and are less dependent on waiting for the work of others to complete first. However, we have found that many these days are aware of the concepts already and need little convincing to adopt them, just a helping hand to get started.