One Startup’s Transformation from Legacy to APIs
Creating APIs doesn’t always start from scratch. Often APIs are added to existing systems. This is done to serve new client-side frontends and mobile apps, or to allow other parties to consume its services. At BeterDichtbij we started with a legacy system but wanted to expose our services as APIs as well. This article gives an overview of our transition from legacy to API, the challenges we encountered, and our plans for the future.
BeterDichtbij is a value-added service concept connecting patients with their healthcare professionals; their doctors, nurses, or GP. BeterDichtbij started as a messaging service, putting patients directly in touch with their own doctor, for example to exchange questions and research results. We want this to be as easy and accessible as possible for both doctors and patients. At this moment BeterDichtbij is used by more than twenty Dutch hospitals for easy and secure communication with their patients. Our objective is to grow beyond the current messaging service to an ecosystem of specific healthcare related services.
The company is now two years old, so we’re actually still a startup. So why, you ask, am I writing about legacy systems? How could such a young company have any legacy at all? Simply put: because that legacy was the basis of BeterDichtbij. When the idea was pitched and a pilot project was first started, the founders didn’t start from scratch. Instead, an existing healthcare communications platform was used. This was a web-only platform based on ASP.NET MVC. One of the core principles of the BeterDichtbij concept was to ensure easy access for patients. And because practically everyone has a mobile phone and knows how to use it, the creation of BeterDichtbij mobile apps was the next step. Another company was asked to create these apps, both for Android and iOS.
As the existing platform didn’t provide a usable API for mobile apps, the app development company created their own backend. This mobile backend was named the midlayer. This system served as a façade for the existing platform. Content data was loaded from the platform, while new features necessary for the mobile apps were implemented in the midlayer.
All of this was done in a pilot. As this project became a success, BeterDichtbij became an actual company in 2018. At that point, the newly formed development team took ownership of the separate systems and mobile apps.
Shedding the Tiers
By now the BeterDichtbij mobile apps were served by several consecutive layers to yield the requested data. For every software change within this flow, three different systems had to be modified, tested and released. This was made especially difficult because the different tiers were implemented using different languages (C#/.NET, Java, NodeJS) and running in different environments (VPS, Docker containers, AWS). It was obvious that this could be done more efficiently.
We started a project to create a single API running on the existing .NET platform to serve the mobile apps. This API would incorporate all features of the existing NodeJS and Java systems, rendering these obsolete. We wanted to minimize the impact on the mobile apps so we implemented the API using the same specifications. The midlayer also stored some data in a MySQL database. We migrated this data to the MS-SQL database used by the platform and the new API. In the meantime the mobile apps were prepared. New versions would use the new API on the platform, implementing the same contract and providing the same data – allowing the patients to continue using the BeterDichtbij apps as they had before.
This was a challenging project but the benefits were very clear. The software landscape had been greatly simplified. This made it far easier, quicker and therefore cheaper, to add new features. New team members would have an easier time getting to know the platform. The infrastructure for the midlayer system was made obsolete, saving us money. And last but not least, the apps now call the platform directly without passing through several tiers, improving the performance and experience of our users.
Extending the API
Apart from the mobile API serving the BeterDichtbij apps, the API has several other areas. One API endpoint allows doctors to directly open the BeterDichtbij application for a specific patient from their electronic health record (EHR). This feature also allows the external system to send data that is auto-filled in BeterDichtbij, saving time and preventing typos.
We also offer endpoints for single sign on (SSO). This lets doctors use BeterDichtbij without the extra hassle of passwords or tokens. To do this in a secure fashion, we provide an endpoint that communicates with the Active Directory of a hospital. Through this setup, the hospital is able to manage its users and their authorizations in a central location: their own AD.
The last few months we have spent a lot of time building a new client-side frontend for doctors using BeterDichtbij. The old and new application will run side-by-side to allow a smooth transition. That’s why we decided to use the existing endpoints for the new frontend. We aren’t really happy with the implementation of these endpoints used by the old application, though. In 2020 we’ll start refactoring this API. In this project we want to improve the technical usability, testability, and performance.
We have many more plans and ideas for the future. All of these aim at making it easier to use BeterDichtbij and allowing further integration with external systems, making BeterDichtbij an ecosystem of services. Imagine, for example, an API that could be used by another medical system to notify a doctor through BeterDichtbij that his patient has supplied new blood pressure measurements. Or allowing a doctor to copy some data from BeterDichtbij to her EHR directly, without having to copy and paste this manually. For these use cases we would create a set of APIs through which systems could authenticate and exchange data.
The Reality About a Legacy
You might wonder why it has taken us so long to leave our legacy behind. Of course we would have preferred to deal with the legacy as soon as possible. But in reality there were several constraints we had to deal with. BeterDichtbij started with a platform that was used daily by patients and their doctors. We also started with a development team that didn’t know the platform. So while starting from an existing platform definitely kickstarted BeterDichtbij, it also steepened the initial learning curve for developers. Finding your way around a new codebase simply takes time, especially when it’s distributed over several systems.
Of course there were plenty of ideas for new features. So initially we spent a lot of time implementing new functionalities while we were getting to know the existing codebase. Doing so, we learned a lot and found our way through the code. This experience was invaluable in actually pointing out the tricky parts that really needed refactoring. It then became a constant balancing act between refactoring the legacy and implementing new features. Some elements, such as the previously described midlayer, were obvious candidates for refactoring. But even in that situation we also considered the costs of refactoring to make an informed decision. In this case the benefits outweighed the costs by far, but that isn’t the case for every piece of suboptimal legacy that we find. Our backlog still contains several items for refactoring. These are improvements to areas in the code that don’t change often, or are relatively minor issues that form only a small share of our technical debt. In the long run we strive to remove all our technical debt. To achieve this we add refactoring items into each of our development sprint.
Legacies Aren’t Built in a Day
We can see that BeterDichtbij has made some great steps in dealing with its legacy. This article described several of the hurdles we faced and how we did it. Dealing with legacy systems is not a trivial matter – it really takes conscious effort and commitment to transform them into proper API’s. That doesn’t mean you shouldn’t do it – on the contrary. But be realistic. Rome wasn’t built in a day, nor was your original legacy system, and neither will its transition from legacy to API be finished as fast as you’d like. Instead of taking this on as one big project, divide it into smaller steps. Isolate the different parts of legacy and technical debt in your systems and add them to your backlog. From here you can estimate both the costs and benefits of each item so prioritising becomes easier. This also makes the impact of legacy components visible to the business and management, creating wider support within your organisation and adding a common understanding of the state of your system. In turn, this will allow your organisation to make a gradual yet smooth transition from legacy to API.