I wrote an article recently on InfoQ about how REST replaced SOAP on the web. The comments rolled in and I found myself if a debate that I have had many times before – “why do I need an integration platform?” There are a number of answers to this, but stripping features away the key principle that answers this question is Loose Coupling. Let me explain.
I grew up in the countryside where coupling is a form of animal dating, so loose coupling makes me smirk a little. Getting past that, loose coupling is an approach to interconnecting the components in a system or network so that those components, depend on each other to the least extent practicable. Coupling refers to the degree of direct knowledge that one component has of another.
“Oh right, encapsulation”. Well no, encapsulation is really an OOP concept concerned with restricting access to data held by an object, loose coupling is more of a architectural concern that addresses the problem reducing dependencies between components in different systems so that the impact of change is minimized. There is a really good post on this subject by Michael Jones that you should read. He posed some questions to help understand how to you could measure loose coupling in a system, and, well I stole them.
The degree of coupling between two components can be qualitatively measured by determining the effects of changing the contract or interface between two components or systems. For example:
- What would happen if you added or deleted a property from a class?
- What would happen if you changed the data type of a column in a table?
- What would happen if you added a column to a table?
- What would happen if you changed you asynchronous email component?
- What would happen if your database server changed from SQL Server to mySQL or Oracle?
In a loosely coupled system the impact of these changes would be isolated to a single interface and swapped out with ease. For the Java folks reading, the JDK already uses loose coupling to hide the details of different relational databases through the JDBC interface.
Where loose coupling matters most
My article on InfoQ was outlining the proliferation of APIs on the web and how that is changing the way we are building applications. As you start to integrate more external APIs with your application you need to have a way to loosely couple your application from these external APIs. These APIs can change at any time and in a tightly coupled system a seemingly innocuous change can break things elsewhere. For API integration I would change the questions above to be more topical:
- What happens if LinkedIn adds a field to the response data?
- What if a parameter type to the NetSuite API changes?
- What if Facebook change their authentication mechanism?
- What is Salesforce changes the way sessions are handled?
- What if Twitter changes the rate limits?
- What if a Twilio API is deprecated?
Anyone that has worked with APIs knows that they do change and often it is to the developer’s surprise.
When integrating APIs into your application, there needs to be some glue code to connect your application to the external API. Developers often see the glue code as custom code that they can write within their application. We’re going to use a donkey dating app to demonstrate:
If you really are just integrating a single API, then home-rolling the glue code makes sense, you don’t want to introduce a new layer for a simple one-off integration. Of course if the external API changes in some way you’ll need to update your application code and test it all again. But if you are integrating multiple applications and increasingly applications connect to many APIs, then introducing an integration tier makes a load of sense. Otherwise you are coupling your application to 3 different APIs so if any one of them changes you must update and test your whole application again.
An integration tier isolates the communication with different APIs or back end systems, meaning if the external APIs change in any way that change only impacts the integration tier not the application logic. This makes it much easier to test and maintain.
This approach of adding an integration tier to your application is very similar to the data tier you already have. You know its bad to pepper your code with SQL statements and data access logic. Instead you use an ORM layer and create simple data access objects (DAOs) to interact with the database. If the database system changes or you add fields to a table the cost of that change is isolated to the database driver or the definition of your DAO. That is loose coupling and that is how you should treat access to all data sources whether a database or the latest equine API.
Tight coupling or Point-to-point (P2P) integration is when you write the code for every API and is frowned upon. P2P integration is generally brittle and because the code is embedded within other applications it is very hard to get visibility into what the code is doing or to manage it over time.
It is still glue code
Many maybe thinking “Donkeys? What the… never mind. But there is still glue code I need to maintain but now I have a new tier in my application”. This is a fair point since there needs to be some logic that determines how the data is presented back to the donkey dating app. However, integration platforms like Mule are designed for an environment where connecting to multiple systems is common, thus has features to ease the complexity of connecting to disparate systems.
Mule Glue Code
Any code you write in Mule is completely decoupled from surrounding implementation details such as transport, protocol, security, transactions and more. A component in Mule is just a POJO that receives data and performs actions on it before returning it. You never get wrapped up in understanding the JMS API or how to deal with a HTTP 302 redirect or managing SalesForce.com sessions when they expire. These things and a whole lot more are handled for you. Some common must-have features that are often overlooked when developers build tightly coupled or P2P integrations:
- Client code – having to deal with JMS APIs or HTTP clients can be frustrating to say the least
- Connectivity – for many of the poplar APIs and applications, specific connectors are provided to make it even easier to work with the API.
- Orchestration – once you start mixing APIs you quickly need to a way to orchestrate different calls to APIs and other systems and collate the results.
- Testable code – Mule decouples code from other aspects such as data format and protocol so that any logic written in a Mule app can easily be tested using standard JUnit tests. Mule apps themselves can also be tested using JUnit.
- Error management – what is the right behaviour when things go wrong
- Retries – non-transactional systems rely on reties to complete requests that failed due to a network glitch when accessing the donkey directory API.
- Security – you probably don’t want to deal with SAML or OAuth 1.0a without some help
- Transactions – if you are using a transactional resource like a JMS destination then it’s a hassle to manage that yourself
- Monitoring – how can you see what’s going on with your integration at run-time
- Data transformation – integration platforms offer varying degrees of data support such as simple object transformation, object bindings, XSLT and XQuery and full data mapping environments.
Loose coupling is about reducing dependencies between components in a system so that the impact of change is isolated. Introducing an integration tier makes sense once you are integration more than one system. With the proliferation of APIs I fully expect the number of applications that integrate with these APIs to grow massively over the next 24 months. Integration platforms like Mule offer lots of benefits for writing testable and maintainable glue code for working with APIs and on premise applications.
No livestock were harmed in the making of this blog.