As a B2B software company, you develop software for other businesses. Those businesses purchase software from you and a variety of other vendors, and they naturally expect that your software integrates with others' seamlessly. So, you need to build integrations to connect your software to any number of other applications in your industry. Easy, right?
Here's the catch: even if you write an integration to every piece of software your customers might possess, not all customers have identical setups. For example, two customers might have the same ERP system, but they might have different versions of the software, or the ERP system might be deployed in subtly (or not so subtly) different ways. Your customers might also have different API endpoints, recurring report templates, access credentials, and a number of other differing things from one another.
You don't want to reinvent the integration wheel with each customer you onboard. The software integrations you build should be generalized in such a way that they can handle disparate customer configurations with a few clicks of a mouse.
In this post, let's look at three best practices for building reusable, configurable integrations that can be deployed to a variety of customers with differing setups. We'll address:
- The value of using built-in components so they can be swapped out readily as specs change
- Why you should write reusable custom components that can be used in multiple integrations.
- How to leverage config variables so you can build generalized integrations that account for differences between customers.
A few years ago, prior to my time at Prismatic, a software team I was on was tasked with writing an integration. The spec was fairly simple: we were to pull XML files from an SFTP server, read data in from each file, process the XML, and post some data to an HTTP-based API. Easy enough. We imported some SFTP, XML, and HTTP request libraries and coded away. The day before go-live, though, the customer had a "small change" to make - rather than an SFTP server, they decided to host their data on a Windows file (SMB) share. My team spent the night ripping out our SFTP code and replacing it with a Samba implementation. A dozen or more dev hours were burned by one seemingly innocuous change.
This sort of scenario is common - specs change, and integration builders are expected to handle those changes gracefully. If you write your own code for common tasks (like interacting with file storage systems), you may end up in the situation I was in: spending hours upon hours refactoring code when a small detail changed.
Let's look at how a scenario like that would shake out if you leaned on Prismatic built-in components. Imagine you wrote an integration that pulls data from an SFTP server, but at the last minute you were asked to pull data from a Dropbox share instead. Credit where credit is due: Dropbox's API and libraries are easy to use, but there is some amount of ramp-up time involved. Rather than immersing yourself in the Dropbox API, though, with a few minutes and a dozen or so clicks you can easily remove your SFTP actions, and replace them with corresponding Dropbox actions:
By relying on built-in components, there's no need to rip apart existing code, write new unit tests, etc. You can simply swap out one built-in component for another. And, if one customer uses SFTP, and anther uses Dropbox, you can even write your integrations to handle both scenarios with a branch component (we'll get to that in the Config Variables section in a moment).
Of course, there's not a built-in component for everything. Lots of what your product does is specific to your industry, and relies on domain knowledge only you have. That brings us to my next best practice - writing reusable custom components.
This is where it's your developers' turn to shine. You and your dev teams know your industry, and the various ins and outs and complexities that come with it. You need to execute bespoke code that is specific to your vertical, and that's where custom components come into play.
As you write custom components, be sure to make them general and configurable through component inputs. That is, don't hard-code things that might change between integrations and customers. Instead, drive your component actions through configurable inputs. It's like writing a programming function that takes several parameters - some might have default values that are rarely changed, but it's sure nice to be able to invoke a function with overridden defaults when you need to.
Suppose, for example, 95% of your customers use a hosted ERP service with an endpoint of
https://acmeerp.com/api, but your remaining customers host their own solution at URLs like
https://example-customer.com/acmeerp/. In your custom component you could make the ERP endpoint an input so your custom component can interface with SaaS or self-hosted instances of the ERP. Further, you can make the ERP endpoint a configuration variable for your integrations and use that config variable to drive your component's inputs. This leads me to my final recommendation - leverage config variables in your integrations as much as possible.
Your customers' configurations will differ from one another, and sometimes in ways that you don't expect. The majority of your customers might have a standard SFTP server setup, but there's always the one oddball who runs SFTP on port 22002 or something (for "security reasons"... as if an
nmap won't find it...).
For that reason, it's best to leverage config variables for anything that might possibly be different between customers. In the case of SFTP server ports, you can make port 22 the default value, and only change it for the one oddball customer.
As you assemble your integration, then, you can add required config variables. Then, as you add steps to your integration you can reference those config variables rather than hard-coding values.
The more of your integration you make configurable, the less you'll have to futz with your integration later as customer configuration changes. If at some point one of your more sane customers calls to let you know that they're running SFTP on port 80 now for some reason, you won't need to fork (make a copy) of the integration and replace all the 22's with 80's, and if they're calling about some value a custom component uses, you won't need to hack up your code. You can simply hop into the instance deployment screen, flip a single 22 to an 80, sigh and mumble something about port conflicts, and then carry on merrily with your day.
In addition to driving steps of your integration, config variables can be used to determine which branch (code path) to follow when many options are available. Suppose, for example, some of your customers are on version 2 of an ERP system, and others are on version 3. These versions have slightly different POST payload requirements - what you send each version needs to be formatted a bit differently. Does that necessitate entirely different integrations? Of course not! You can simply create a config variable - call it something like "ERP Version" - and configure your integration to generate a v2 or v3 payload based on that config variable.
If your customers ever upgrade their "ERP v2" software to "v3", all you need to do on your end is increment an integer from 2 to a 3 for a customer config variable and redeploy their instance. Their updated configuration will drive their integration through the correct "v3" code path.
We talked about three best practices: using built-in components wherever you can, writing custom components that are general enough that they can be used in multiple integrations, and driving integrations with config variables. If you'd like to read more about these topics, I recommend checking out a few articles in our docs:
If you're not already using Prismatic, you can start exploring the platform with a Free Plan - no credit card required. If you have any questions or want to talk about integrations in your field, please reach out - we'd love to chat!
Prismatic is the embedded integration platform for B2B software companies. It's the easiest way to build integrations and provide a first-class integration experience to your customers. A comprehensive solution that empowers the whole organization, Prismatic encompasses a purpose-built cloud infrastructure, an intuitive integration designer, integration deployment and support, and an embeddable customer experience. Prismatic was built in a way developers love and provides the tools to make it perfectly fit the way you build software.