Creating A Platform: Overly-Simplistic API Strategies
Updated: Jul 29
Platform. There are books like Platform Revolution and The Business Of Platforms that tell us that we want to make our products “platforms” or we want to build a business model where in our products we can facilitate the exchange of data with other products. In doing so we gain access to more customers, make customers stickier, and ultimately, we do more of what the promise of computing in general is meant to do: we make the people that choose to use our products more efficient (which in turn makes our products more valuable).
So we want to create a platform. There’s just one problem: every build takes valuable time away from features we want to create and then makes our products more expensive to own and further develop. That is, unless we can sway other organizations to integrate with our product. The more users our product has, the easier this becomes.
We see this most acutely when we talk to product teams or developers at other organizations. I can’t tell you how many of these calls have ended with a vendor in an adjacent market agreeing we should build an integration but leaving it up to the company that has the smallest user base (and so the most advantage in the relationship) to build the integration. Often, neither company has a great stack of technologies for building an integration and so the project just dies… Even though both parties see a lot of potential benefit in an integration. But it doesn’t have to be that way.
Enter the API
An API, or Application Programming Interface, is a set of functions and procedures that allow access to features in a controlled way. Sure, we could allow others to write directly into our databases (or disks if it’s an Operating System) but that can be dangerous, so we need to provide a way for other developers to do so following rules that reduce the risk of having others interact with our software.
In modern SaaS architectures, the API is usually a collection of REST endpoints. Each allows a tool to Create, Read, Update, and Delete objects in our software. Those operations are camel-cased because they’re often referred to in SQL as a CRUD framework and while there are more mature ways to conceptualize these, they represent a good basis of understanding without getting overly technical.
Let’s look at an example. Let’s say we have a database of parts in a warehouse at an organization called Pretendco. We might make a REST endpoint called Parts and allow another vendor to lookup a list of parts by calling https://pretendco.com/parts. We could then return a list of parts and if they then wanted to view information (or Read the information) on the part with an ID of 1130 they might call https://pretendco.com/parts/1130. We can then allow them to update the information or delete by sending different parameters. In order to allow for different data structures and more complex operations like authentication and authorization we then get into more detailed REST commands, but that’s a basic explanation of an API endpoint.
Why We Need An API
When two software companies exchange data, it’s usually done using an API. This allows us to specify rules for interacting with our software in much the same way we do when users put data in. If we have a required field on the front end/GUI/web interface, then we would want that same field required in the API. If we require a number in the phone number field, we’d also want to require a phone number in the API. That provides consistency and so keeps the integrity of the data.
We also provide rules for which vendors (often represented in the form of a unique API key) have access to various pieces of data and what types of operations they can perform. Consider this, when we take a photo using a third-party photo app on our iPhone, we get prompted to grant access to that app. If we accept, we’ve allowed that vendor’s API key access to the API that makes the camera work on the phone. This way, Apple has provided a means for vendors to access features on our phone safely, and only when we grant the level of access required. The same becomes true when providing access to one piece of software in another, and each endpoint is programmed in a way that allows for that access to occur when authorization to do so is present, or accounts for what happens when that authorization is not present.
There are other reasons to build a good API:
Allow customers to automate processes around our product.
As we grow, our customers will demand it.
Provide a better framework for testing our own tools.
Gives us the ability to create more interfaces for products faster.
Break apart monolithic blocks of code.
Reduce the code required for various functions.
But for the purpose of this article, let’s keep our eye on the value of the API to external vendors for a bit.
So the API is where the rubber meets the road in becoming a platform company. This is also an area where an upstart company can shine. Microsoft rose to dominance over a number of superior operating systems in the market not due to subterfuge as many at Apple might argue, but because out of the gate, Microsoft copied the APIs from an operating system called CP/M when they built DOS. This meant that upon the release of DOS, every application built for CP/M worked on DOS. And the initial versions of Windows allowed for a protected mode that ran all of those applications, giving them over ten years worth of apps that ran on their operating system. They became a platform by having a great API.
They then leapfrogged the Mac with Windows by providing an open platform with more options than the competitors and being an early proponent of making that API object-oriented. Companies like Stripe were able to grow to over $30 billion dollars by appealing to developers more than anyone else. And they did that by being API-first.
The API-First Strategy
Organizations build software in a lot of different ways. An API-First strategy is one where we build the API-endpoint and then we build the various ways the people that use our products access them: a mobile app, a web front end, an integration with another tool, etc. We build an endpoint or collection of endpoints that facilitates the operations required by those tools that consume the output of that endpoint.
The Stripe documentation offers a great insight on what it means to be API-first. When we read how to do something, we see how the API works before we see the graphical screens users see. By building the endpoint first, we are able to make sure that every task a user might perform in our front-ends is available through the API; and by being in the API, able to be used by other products.
Over the years, we’ve seen a number of API strategies employed at various organizations. Each has their pluses and minuses. But API-First is always the best. This makes our applications less monolithic in nature (and so cheaper to maintain over time) but also forces us to treat third party integrations as first-class citizens even compared to how we handle our own sites and apps.
The API-first strategy starts with understanding how our application is architected. In the SaaS world, there is usually a database where all our data lives and then there are the aspects users interact with, which we can refer to as the front end. The application is going to connect the front ends (web apps and apps on devices) to the database. That has a bunch of endpoints as we described above. Rather than have a large application that does both, we might have a front end web app built in let’s say React and a back-end built in, let’s say Java. React then calls endpoints provided by Java, which Java then processes.
That’s pretty overly-simplistic, but making sure that every task the front end performs is available as an endpoint is central to being “API-first” and if we’re already building logic into the front-end that can’t be performed by a third-party using those endpoints, then we’re starting to drift from the goal of being API-first. We should try not to build software that violates that manifesto and keep a running list of those where we built something that needs to be remediated.
When possible, the best API strategy is API-first. However, many apps have been maturing for a decade or more and so there are other strategies to employ, albeit hopefully just en route to being API-first.
The Workflow-Based API Strategy
The next strategy we’ll look at is workflow-based APIs. Here, we try to think of a list of everything we want another vendor to do with our data and build endpoints to facilitate those transactions. The really great thing about a workflow-based API is that vendors who are doing the tasks we thought of usually have a curated and easy approach to build integrations with our product. Third parties can get up and running quickly and provided they only do what we think they’re going to do, we can easily build the facilities to enable their tasks and keep them updated.
Over time, a workflow-based API is really telling a fragmented story of how our products can be used. We don’t know what kind of innovations others will create with our products when we expose the whole product to APIs. I’ve seen companies re-invent themselves based on how their products get used. Some have become hubs that facilitate tasks in other products, others have realized huge value in areas they never considered.
Another drawback of a workflow-based API is that we have to maintain endpoints we built for the express use of third-party integrations. When we build new features, those become second-class citizens and interacting with those features are often put on the backlog. We have to maintain a workflow-based API when we update features and so we might end up breaking third party integrations in regular updates if we aren’t testing for every way a third party might interact with our APIs. And we have little to no control in how that happens. This becomes dangerous as we grow and as our integrations get used more. The value of the increased productivity ends up potentially getting offset by the negative value of having that productivity unavailable while we fix what we broke.
Still, companies with monolithic apps and a lot of history behind the logic in those apps might need to start a platform strategy by building a workflow-based API - given the huge amount of work required in moving into an API-first based approach to software architecture.
The Data API Strategy
Most software is just a front-end to a database. We put data into the database and recall it. One common practice when building an API is to just wrap the database in a REST interface. Here, we build a 1:1 map of our database in endpoints. We’ll refer to this as a Data API.
Data APIs also don’t take into account much of the logic we create in our apps. Over time, we add logic. We define certain fields as required, we transform data as it’s entered (e.g. from a date stamp to epoch time), and we present data differently when it’s recalled in screens. We also break initially simplistic representations of data up into multiple tables and add operations where various tables update one another when needed. In short, our app gets complicated.
Data APIs can expose too much data or too little. We can cause too many requests to construct an appropriate representation by forcing users to perform too many queries to find all the pieces of information we might have otherwise exposed in a workflow-based API or documented well in our own findings building a front-end if we were API-first. We also might forget to limit what’s allowed in our database and allow for inconsistency in the data, causing what our front-end might consider a bug.
Data APIs can be great for simple apps; but most apps aren’t simple. Even if an app is simple, as we create additional value for customers it’s not likely to stay that way. Anyone embarking on adding an API on top of the database schema should do so with careful deliberation. Not only around what gets exposed, but how another vendor might be able to actually represent our data.
Often, if a Data API will be employed it should be paired with a workflow-based API.
Every few years there’s a new hotness in software development. The latest hotness in the API world is a Graph API. A Graph API is an API that builds on the concepts of a REST API but allows for a more object-oriented approach, with a focus on the relationship between various resources and their related objects.
The concepts required to understand a Graph API need their own article. But suffice it to say, it can be incredibly efficient and useful. Any organization without an API that’s looking to implement a new strategy should rule out a Graph API before moving to any of the other strategies.
A Graph API is also great to ease into. We can build an endpoint that exposes a number of options and then as partners need additional fields, we can expose those as well. and especially if we've already begun to leverage an ORM (e.g. Hibernate), once all the internal developers get trained on it, we can building our front-end using the Graph API as well.
Again, anyone that doesn't yet have a customer-facing, or partner-facing API, should start their process of considering an API strategy by eliminating the option of a Graph API before moving to any other strategy - and consider that the best strategy is often to have a combination of all those considered.
Along the way in building out a clear API strategy there are finer points we’ll discover. Often we don’t understand the importance of various aspects until we get bit by not having them. Let’s look at a few of those implementation details now:
Authentication: How will other vendors authenticate to our app? We should plan for more than a basic key and we should plan for tenants in a multi-tenant architecture to either distribute keys or preferably to leverage federated access solutions out there (e.g. Okta or Azure Active Directory) to distribute keys to access their tenants. Those solutions might be ones we consume or the tenant might bring their own. Unloading the liability of keeping keys in the database is always preferred, even if we’re salting hashes and all that good stuff.
Authorization: Vendors can call this something different. But once a process is authenticated, what does that process have access to. Apple calls these Entitlements and prompts users the first time an API is called that needs access to specific resources. The Microsoft Graph API has a global authorization a tenant own allows for and then each user provides authorization to given resources. The security posture of an organization will mature over time and the way we grant authorizations to given resources will become more complicated. But if we plan for more than a run of the mill CRUD framework when initially building our app, we can build parts as we mature and not redo much of the work to ship the first versions of our APIs.
Rate Throttling: We don’t want other developers hitting our endpoints too much. This allows for DoS or DDoS attacks but also presents a concern around the ability to brute force keys.
Pagination: It’s inefficient for us to give more data than we need to. It’s also inefficient for others to get more data than they need. We can limit the results in a query and what information is provided with each query. Once another vendor has processed the first set of results (or page), they can move on to the next with a subsequent call.
Response codes: We need to know when a process worked and when the process didn’t work. Response codes can tell us all those details much easier than unstructured json in a payload and if we stick with common response codes, other developers will quickly be able to understand what’s happening. At a minimum, try and include 200, 201, 204, 400, 404, and stay with the way those are spec’d.
Documentation: We’ve all been frustrated when developing against another organization’s API. Much of that frustration could have been resolved with better documentation. Whether we’re ready to use an automation documentation repository like Apigee (https://docs.apigee.com) we should read up on OpenAPI (we used to call this Swagger) and build the framework to automate our API documentation early. The later we wait, the more it will seem like a heavy lift and the more we’ll be reaching in the cobwebs to remember how we meant for something to work. It may seem like more work, but it makes us a better partner to third parties and it makes training new people on our own front-end teams much easier.
Webhooks: Most of this article has been about our own API. We can also create webhooks, which allow us to send information to the API of another web application in the event that some action happens in our app. Think of this like APIs are organizations pushing information to us and web hooks are them receiving event-driven data. Hopefully by providing a great API, we can use better and more modern techniques to interact. Check out tools like Zapier ( https://zapier.com ) to see how a lot of different services can be daisy-chained together to do some pretty cool stuff with webhooks.
Versioning: Our app will mature. We will need to decommission endpoints and alter the output of endpoints. Versioning with a /v1 or /v2 either globally or per-endpoint will allow us to do so without introducing breaking changes to our own assets that consume endpoints or third parties that consume endpoints. We can then set a time limit for how long we will maintain old endpoints and communicate changes to developers.
All of this might seem like a lot. But in many cases, we can just get a solid understanding of what each is and write our code around building aspects later. For example, just add the versioning in the URL scheme at first. This gives us the ability to version later without changing URL schemes. The point is to do a little planning to potentially save a lot of effort later.
Marketing the Platform
Now we have an API strategy. As we build endpoints (or expose them if they’re already built), we can have more meaningful business development conversations with third parties. If they don’t have an API then even if they’re larger than us, they’ll realize it’s more logical for them to build some of the integrations.
Becoming a platform means we create value by owning the exchange of data. This will be a must as our user base grows. But facilitating these exchanges can also create a network effect based on having multiple other organizations working with our data and getting additional customers by cross-selling and cross-marketing with our new partners.
Once we have integrations, we want to push the platform strategy and doing so means aligning our sales and marketing with those of our partners. So as we’re on those business development calls, we want to be looking for ways to get in front of sales teams and systems engineers and/or getting our brand represented in the marketing assets like blogs, social posts, articles, help desk FAQs, etc. This follow-through to the technical innovations solidifies us and the more integrations we have, the clearer we are the platform the other vendors in adjacent markets should build integrations with.