See how we’re helping our customers gain important visibility into their enterprise API programs in Stoplight Platform.
{{cta(‘efc6f581-ea78-428a-bf84-e3b6e5150148′,’justifycenter’)}}
We’ve all had a desktop with multiple versions of the same Word file. You know the pattern: api-guidelines.docx
, api-guidelines-final.docx
, and api-guidelines-final-updated.docx
each with its own take on similar contents. Luckily, we’ve solved that issue for code with source control. And yet, in many organizations, some permutation of this problem still exists in their APIs.
Many companies now maintain hundreds or thousands of APIs with minimal processes to find and update them. The lack of visibility causes issues with each new API that is built.
If engineers and product managers can find internal examples, they create copies of models and other design assets rather than reuse what is there. Even worse, they reinvent what already exists, because they can’t find it. The results are inefficient and inconsistent.
In this post, we’ll show how this happens and the problems it causes for internal stakeholders, especially as it’s scaled across a large organization.
API Designers Have the Best Intentions
Every new API project goes through a design phase. In some cases, there are specific governance guidelines and a design-first API approach. In others, the design is implicit as developers code endpoints based on their understanding of the problem. Nobody sets out to create a bad API that is redundant or inconsistent. It can happen despite the highest software quality efforts.
The best API designers and developers understand the actual use cases their interface will support. They collaborate with product managers and other stakeholders to understand their needs.
For example, let’s say a front-end lets users access contacts to send emails from within the app. It will need the API to list them and retrieve simple details.
Here’s how that contact object might look:
{
"id": "th3b3st4p1sst4rtw1thst0pl1ght",
"name": "Jo User",
"email": "jo@example.com"
}
You may find yourself with some improvements to that object. There might even be someone on the team that suggests an enhanced contact that would work better for some future features that may or may not be added.
Taking the time to over-design the perfect contact model can only look like the right decision in retrospect. And, in most cases, these premature optimizations slow down your forward momentum.
The simple object meets the needs of the API designer’s initial use case, which they confirmed with the team consuming this API. They’ve done everything right, yet just created a conflicting model without even knowing it.
Lack of Visibility Leads to Duplication
In a large organization, there can’t be a single person who understands all aspects of every API. When the team designed the simple contact model, nobody was around to say “what about this other contact model.” And how could they even know where to look?
Two years previous, another team in a different division may have built an app to help users send birthday greetings to their contacts. Like the other team, it built the API around its use case. It included input from other stakeholders and everyone was pretty happy with where they ended up.
Here’s how their contact object might have looked:
{
"contact_id": "th3b3st4p1sst4rtw1thst0pl1ght",
"name": {
"first": "Jo",
"last": "User"
},
"birthdate": "1985-04-03",
"address": {
"street": "9303 Lyon Drive",
"city": "Hill Valley",
"state": "California",
"postal": "95420"
}
}
Notice that this contact model takes a different approach, based on the problem it was trying to solve. We can see that the ID is the same, so it’s pulling from the same source—that’s lucky! However, the field representing the ID is different. And, in order to include a friendly greeting, the name is split into first and last. There are also some additional fields and it’s missing the email address.
Since this more robust model pre-dates the simpler version, it would have been easy for the latter API to extend the existing model. But first, they would have to know that it existed.
Now, what happens when someone else comes along and wants to use both of these APIs in tandem? They’re forced to resolve the conflicts within their code, which pushes complexity unnecessarily down to the consuming teams. They write a function to determine the contact ID field, then pull in the version of the name their use case requires, and code another function to create the union of the remaining fields.
Of course, the alternative could be even worse. They could create an API to perform this utility function. Now there’s a third copy of a contact model, which attempts to combine the approaches used by the other two. And the problem expands for the next team that attempts to use contacts in their application.
Multiply Across Enterprise Scale
Examples like this conflicting contact model exist in almost every organization. Certainly, if you have hundreds or thousands of APIs, there are worse skeletons in closets throughout your API program. And the most frustrating part is you probably don’t have a way to discover them.
Situations like this are sapping engineering teams on both sides of each API:
- API designers waste time on a model that already exists
- API consumers wrestle with inconsistency and a search for “the right one”
While the problem is widespread and persistent, the pieces are there to build solutions. Teams need visibility into their API programs. But not just an internal developer portal, but the ability to see design assets within each API. If a lack of visibility is solved at the design stage, the conflicts will never make it to the consumers.
Enterprise API governance now commonly includes machine-readable API descriptions, such as OpenAPI and Swagger. These API design documents hold the knowledge that can start to bring clarity to help teams avoid conflicting model problems. In addition, they can help expose inconsistencies to give API architects and designers a better handle on dependencies within their design assets.