It all started with Equals Money, a company founded in 2005 aiming to simplify money management for everyone using modern technology. To achieve this goal, they offer a wide range of financial solutions for personal and business use, including software for payment processing, card handling, and internal budget management.
Moreover, there is an even wider range of external systems connected to Equals Money’s systems through API.
The situation described above presented several challenges:
Problems with the API and documentation were well-known across the company. Our first challenge was to propose an optimal solution and convince developers and business decision-makers that we could achieve it gradually, within a reasonable time frame, or revert if necessary.
Furthermore, the solution had to be consistent with the company’s overall security protocols. We needed to ensure that the documentation contained exactly what we intended to show, no more and no less.
We also cooperated with the sales team to gain knowledge about what we wanted to share publicly, to demonstrate the services we offer.
It was the kind of project that revealed itself as it progressed. We didn’t know the exact details of what we needed to do or what the final outcome would look like.
We started with a technology overview, checking what was available on the market and creating a prototype. After several iterations and revisions, we reached a point where everyone was pleased.
First, we needed a central contract repository—a separate element within the whole system to collect data in one place and define all the documentation and information flow.
Consequently, every contract would be defined only once, in contrast to many solutions that were popular a few years ago, such as contract tests. These tests were meant to check every data schema for correctness and compliance with declarations between different applications.
Our solution ensured that contract tests were no longer necessary. With a single central repository used in every internal application, it became impossible to make such mistakes.
We could catch potential problems faster on many levels. From a business perspective, this is a priceless solution—it allows the company to save significant amounts of money and prevent image problems by finding errors and inconsistencies before a client can spot them.
Additionally, we proposed replacing .yaml files with API and documentation in the code. Typescript and zod. libraries were chosen for this task as a more natural and developer-friendly solution.
All API and documentation would be in code, making it easy to import information from the repository for different applications or duplicate certain fragments for other projects.
We deliberately picked TypeScript and zod. so that the new and old technology would have a common area: OpenAPI. Having this common element was crucial for migration, allowing us to arrange everything together.
Moreover, systems used by Equals Money require creating documentation in the OpenAPI format to automatically generate all the API descriptions. It’s a common practice in financial services to automatically generate documentation, especially for developers, because it ensures the documentation is almost always up to date with no human interference needed. When something changes, it’s reflected in the documentation almost immediately. This helps ensure there are no errors or inconsistencies.
This type of migration has another benefit—during the process, we examine every service in detail. Every endpoint is tested both automatically and manually. Testers thoroughly check the entire system, effectively creating a solid inventory.
Additionally, we can identify and address any missing elements. We can also spot outdated components or areas for improvement.
Throughout the process, we aimed to create additional benefits by leaving the code better than it was.
The whole process was rather complicated. We needed to integrate the old technology with the new one, along with a few different technologies, using a common standard: OpenAPI—a consistent and precise standard for defining contracts and APIs.
We utilized this standard to produce schemas in the OpenAPI format. Furthermore, we then combined them into one final contract.
As a result, everything is now in more recent technology without losing any functionality. Features such as contract validation, incoming and outgoing data validation, error handling, and logging are at least as good as, if not better than, the old solution.
During the process, we needed to verify the correctness of the emerging documentation by checking every endpoint, making it a slow process. Transferring complicated schemas to new technology requires accuracy and time to ensure uninterrupted service for clients.
Moreover, developers needed to learn and get accustomed to the new technology. This transition required them to step out of their comfort zones, necessitating a patient approach. There were many questions about how to do things and how the new system worked.
We had to thoroughly and properly describe the new technology to enable everyone to use it in their everyday work. It had to be simple, intuitive, and, most importantly, better than the previous solution.
Every change carries risk, and a change of this magnitude in the API requires a very responsible approach, especially in the financial industry.
The whole project is not finished yet, but we are already seeing the first results. The most visible effect now is how much work it saves, especially for front-end teams, who often duplicate fragments of code from the documentation.
Thanks to the central repository, they always know what kind of data will be received, what needs to be sent to the server, and what will come in the response. They don’t need to replicate it based on .yaml files; they just have a prepared component to embed on the site. There’s no need to check or worry about data correctness and consistency.
All of this also means that there are far fewer errors in the code.
Another result we are seeing is automated documentation. The central contract repository makes it much easier to create tools that describe system architecture or automatically check which services are exchanging data. Based on such a tool, we plan to create diagrams of data exchange across our entire system network.
These automatically created diagrams will always be up-to-date, accurately showing the flow of data. This will be especially useful for software architects when designing new functionalities.
Another benefit we are already seeing is the detection of components and services that are no longer used but still maintained. Now we can remove those parts of the code. Less code means easier work, lower costs, and less wasted time—all of which result in significant savings for the company.
Additionally, by checking all the endpoints, we found and corrected a few inconsistencies right away.
Moreover, we started to validate not only incoming data but also outgoing data, allowing us to detect potential errors as soon as possible.
Our goal is to achieve an always up-to-date, reliable API and documentation for all the company’s services, ensuring compatibility between what we declare in the documentation and the data and information that we send and receive in reality.
Internally, the central contract repository means easier API and documentation management, automation, tracking of how individual services communicate, in which order, how often, and creating diagrams based on that information.
As a result, we will always detect unused services that are unnecessarily maintained.
An organized API poses a common challenge for companies with multiple microservices.
Although there are a few solutions designed to support consistent API and documentation, such as contract tests or hexagonal architectures, there is no standard solution to this problem that has gained widespread acceptance in the corporate world.
Our idea of a central contract repository to be shared between applications is definitely a good solution for small and medium projects.