Application integration is often a challenging task, but its ultimate goal is to quickly and cheaply reuse data and/or services with an acceptable level of long-term maintenance. Every time someone does it in a quick and dirty way, another person will shed some tears down the road.
I’ve worked on a project that Objectivity took over from another company. We inherited a set of applications that were integrated in a quick and dirty way, which saved the previous developers about 2 Man-Days (MD) but fixing security and performance issues that this solution generated for all applications took us a dozen of MD. The math says: quick and dirty is not worth the cost. Fortunately, there is also a way out of this conundrum, so let me share the lessons learned here.
(Just keep in mind that the problems and solutions that I describe here concern big apps only.)
There was a headless application, let’s call it The App, that had a REST API consumed by other apps – let’s call them App2 and App3. The App was a system with a microservice architecture and used Azure Service Bus (message broker) to communicate internally.
Now, The App was not equipped with certain functionality, so to solve this, the developers gave App2 and App3 access to Azure Service Bus connection string of The App. In effect, App2 and App3 not only listened to the internal communication stream of The App but also added messages to it.
For the time being it’s all fine and dandy (more or less), because one can live with a couple of irritating issues:
- It’s challenging to work with the messages of The App because if you change their pattern, App2 and App3 will stop working. Messages became application contract exposed by The App.
- Sometimes you have a feeling of working in a strange and indeterministic realm because you see messages that appear in the Service Bus out of nowhere.
- The App’s security is pretty much non-existent – everyone can see what happens inside it.
But when you need to change the underlying technology, you need to also change the communication patterns. App2 and App3 stop working.
How can we avoid this problem in the future?
- Never allow outside apps to access an internal message broker.
- Integrate apps through REST API.
- If you really, really, really need to integrate through a message broker, you need to create a new, separate one.
How can you solve this problem if you’re lucky?
We were lucky and had maintainer access to App2 and App3. We created REST API endpoints and push notification capability in The App and made App2 and App3 communicate through these endpoints. Moreover, there was no technical reason to use message broker integration.
How can you solve this problem if you’re not lucky?
If we didn’t have access to App2 and App3 or message broker bus integration was required because of technical reasons, our best option would be to create a new message broker dedicated to The App’s internal communication. The old message broker (The Tainted One) would have to stay an outlet for integration purposes. We’d have to create a new, correct version of REST API, wait for the outside apps to apply the new rules of communication, and then remove the old dependencies.
At the end, to make that happen think of all deployments for The App and for all dependant applications.
Quick and dirty is… Dirty
As I said in the beginning – quick and dirty can be tempting at times, but often it becomes long and dirty. Using dirty solutions – there’s always someone who must eventually clean up the mess.