IG’s journey towards RESTfulness began as a set of REST APIs built for our mobile platforms as an aggregating façade over our internal services. Two years into the journey we realised that we were building an inflexible monolith that tried to support front-ends with very different user experiences, and which required constant enhancements. Change became painful.
We first introduced blue-green deployments to reduce the deployment risk and the operational cost of rolling out changes. However, the monolithic API provided features which were on the critical path such as trade execution, so even simple changes required a lot of testing. We had to decouple dependencies and break down the monolith into manageable chunks.
Breaking the monolith
We focused on:
- improving automated regression testing to enable QA to take ownership of the release pipeline;
- adopting BDD to allow QA teams to understand code coverage and also to allow them to specify and write additional test cases;
- decoupling services to allow team members to work independently producing better code faster with less merge conflicts;
- enabling other teams to build their own APIs in a consistent manner; and
- enhanced API features such as versioning to build cleaner APIs.
The result of this was a micro-service architecture of independent but consistent edge services providing APIs to our front-ends and clients. We streamlined the process of creating new services running on their own instances and created common tooling to reduce boiler plate code and enforce cross-cutting concerns such as:
- application security;
- error handling;
- request validation;
- routing and a consistent user experience;
- content negotiation and transformation; and
- session management.
This architecture has enabled API developers to easily spin up new edge services and focus on business requirements. The consequence of this is that greater API governance is needed to ensure consistency across the growing collection of APIs.
The road ahead points towards a building an enterprise resource-oriented architecture where not only edge services but also backend services adopt this approach. This will mean thousands of resources hosted on a continuously deliverable set of micro-services. We envisage that most of these resources will be cacheable at the web layer via expiry and e-tag headers, reducing the myriad bespoke caching solutions, and drastically improving performance. We will need to revisit our routing strategy, as we may also want to deploy our services on containers such as Docker to fully leverage our infrastructure. Dynamic routing would decouple the services and enable us to seamlessly move instances between different servers and clusters without requiring code changes.
The result? A highly performant, elastic API ecosystem that maximises our use of infrastructure and development resources, and most importantly will improve our customer’s user experience.
About the author:
Lucas Gut Galan works as a software developer on the IG Public API team. Find him on LinkedIn.