API Fortress is an automated continuous testing platform for APIs that can be deployed in-house or on the cloud. Thier list of clients includes GoPro, Getty Images and MuleSoft (just to name a few). We had the pleasure of speaking to their CTO and co-founder, Simone Pezzano to discuss the journey they underwent to choosing RabbitMQ for their microservices architecture, why they felt it was the right tool for the job and how they’ve used its capabilities to build a succesful platform. The result is great example of how and why to move to RabbitMQ for a long-term harmonious micro-service architecture with improved performance.
API Fortress and RabbitMQ – The discovery phase
The initial concept of API Fortress was born in 2014. They were working with APIs for various companies, and realized that there was no system to test and monitor the APIs without writing a test suite in code. After searching the market, they realized there was a definite need for a better, more modern approach to testing and monitoring, so they started building our platform.
In the early days, as they were gaining customers, they gathered critical insight about the most common testing and monitoring use cases. One of the top use cases involved a transition from legacy monolithic systems to a more contemporary microservices architecture. This trend had dovetailed with the explosion of APIs and API management platforms like Apigee, Mulesoft, Mashery, WSO2, and Kong, etc.
In 2016, they decided to undergo that change, and converted their platform into an entirely microservices-based architecture. During that process, they realized that it was very important that the platform leverage a tool capable of seamlessly orchestrating asynchronous messaging across heterogeneous components. This tool would need to indicate the importance of each message, pointing to whether the message represented a notification or an important task to execute. During setup, it would need to help us scale our microservices-based platform as much as needed horizontally for a multi-tenant cloud system but with negligible overhead, which was highly desirable for our situation. Additionally, it would need the tool to be able to deploy with our platform on-premises.
Their search for the right tool led them to RabbitMQ. Not only would RabbitMQ let them reach the goals of API Fortress, several unique features of RabbitMQ opened a whole new set of possibilities. In fact, they planned several key architectural improvements based on the new capabilities found in RabbitMQ, including:
- RabbitMQ’s powerful message routing settings allowed us to better shape the flow of events throughout our platform. By increasing the efficacy of each message, we reduced the complexity caused by message replication, and subsequent remedial actions in case of failure.
- Standardized AMQP protocol and STOMP support allowed us to create message queues that were not just internal, but also usable by our customers when reacting to certain events with their internally built software in any language.
- High configurability of Queues and Exchanges using the default client libraries in RabbitMQ allowed us to delegate 100% of the setup operations to the pieces of software that actually use the queues, reducing the uncertainty introduced by custom maintenance sequences.
- The costs and skill requirements for day-to-day maintenance dropped to virtually zero.
RabbitMQ provided all of these features and more with unparalleled stability and a minimal resource footprint. Whether powering our cloud platform with thousands of messages being exchanged, or our Docker on-premises deployment, RabbitMQ is the component helping to drive our platform’s success.
The API Fortress Architecture
To help better understand how RabbitMQ solved many past problems for API Fortress, but then also opened our architecture to new possibilities, we can take a deeper dive into how RabbitMQ infiltrates into all aspects of the API Fortress platform in the following:
While it may seem a little intimidating in its complexity, the key factor to understand is that RabbitMQ literally coordinates the majority of all API Fortress microservices. Without going into too much detail, here are several factors that should be highlighted on that point.
RabbitMQ gives a quick solution to allow the microgateway to not care how the messages are delivered by simply asking RabbitMQ to take care of the payloads. This approach allows the Storage Microservice to only accept as much load as it can possibly bear, leveraging RabbitMQ’s QoS as it writes the payloads to the database.
Tests may fail to execute properly when accepted by one of the engines, however, the .ack-.nack system in RabbitMQ makes sure that if it happens, the test can immediately be requeued to execute later. Combined with the the QoS system, we can accurately decide how much load each engine is allowed to accept, making sure the platform does not get congested. To add some extra spice to this, each message from the scheduler can be configured with a given execution priority, which is a very desirable option, especially when thousands of tests are scheduled every five minutes, and some of them are more time-sensitive than others. Finally, as tests get accepted and acknowledged at a somewhat relatively slow rate, RabbitMQ Flow Control can apply back pressure to the Scheduler so that the queue maintains a reasonable size.
Downloaders are microservices that perform I/O operations on behalf of an engine. While this communication is generally solved with an HTTP call, some downloaders may live on-premises behind a firewall. RabbitMQ comes to the rescue offering us two solutions:
- An RPC-like functionality that allows an entity (in this case, the engine) to ask for something (to the downloader) and then expect a response
- A STOMP connector that allows us to expose a dedicated queue as a websocket.
The combination of these two features allows us to deploy the downloader on-premises, initiating a stable channel from the inside of the third-party datacenter and bypassing inbound firewall rules.
Multiple aspects of a test execution may need to be notified to users in a variety of ways. In our system, the Mailer sends emails while the Connector triggers Web Hooks. Third-party notification systems can also be added in the mix, with the internal notification system completing the picture. RabbitMQ Fan-out exchanges allow multiple notification systems to subscribe to the messages they’re interested in and just receive them as they are made available.
Sometimes, notification systems may need certain types of extra information to complete their jobs, e.g., email recipients. Because, by design, they don’t have access to the database, notification systems leverage the same RPC-like system we previously mentioned to ask the Engines for the information they’re missing without the need to discover what engines are available, where they live, and how healthy they are, etc.
API Fortress undertook the same journey as many of their customers. Everyday, thousands of customers leverage the API Fortress platform as they transform from a monolithic architecture to microservices. By leveraging RabbitMQ, much like their customers who are working towards event-driven architectures and other patterns, they have established the foundation to grow and expand their capabilities without sacrificing performance.
To learn more about the automation of continuous API testing, check out the API Fortress website.