Various Variables Effecting API Design
Back in 2009 I was helping companies break free of their confines, building a big-ol’ REST API to replace their big-ol’ SOAP, or Hodge Podge API. This trend continued for years, until somewhere in 2011 it felt like everyone was getting into Service-orientated Architectures again, before microservices eventually took that momentum to a whole new level.
At WeWork we have APIs, services, microservices, and applications with a few dodgy AJAX endpoints. I couldn’t tell you how many, but hazarding a guess I’d say upwards of 40.
That’s incredibly different from the companies on the more classic model: “One API to Rule Them All.” At my last job there was one mega-API in the middle, with one billing service that the clients called, and the API also sometimes chatted to. That was just two, which made it a little easier to keep track of things.
Plenty of companies literally just have the one system, right there in the middle of everything.
Fewer APIs = Fewer Cares
Everything from versioning, paradigm, data format, deployment strategies, interest in hypermedia, etc. all change when you think about these differences.
If you as a company are all sitting down together to plan deployments of “v2 of the app” and that means deploying v2 of the API, v2 of the iOS app, v2 of the Android app, etc., then there’s a very strong chance you don’t care at all about hypermedia, because you have full control of your clients and don’t need them to be smart.
You might not need to specify your data, because you all know that
"distance": 123 is yards, and
"status": "processing" means the warehouse is processing the order, and not that the payment is still processing through the payment gateway. (Stolen example from Derek Prior.)
You might not care about HTTP evolution, because you’d just flop out a new version, and not worry about backwards compatibility.
With that you’re basically just RPC, so the temptation to go full RPC might take over and it’s just
POST /CreateUserFromiOSv2 from here on out.
More APIs = More Cares
If you’re a company with 20+ apps, then all of this stuff starts to matter a whole lot more.
Specifying your data becomes a lot more important when you literally do not know who is going to used it, and they’re in different countries with different metric systems and their default assumptions are not the same as yours.
You might want to consider evolution, when the idea of asking 20+ teams to rewrite a bunch of their code sounds more intimidating than the comparatively simple task of maintaining your contracts beyond what is merely convenient, until a new representation + URI is absolutely required.
You’ll also want to start looking into API Gateways such as Kong, to stop needing to rebuild token management in every damn service you build.
Public / Private
A small team with one/few public API suddenly have all the problems of the large company just mentioned, where specifications and contractual obligation become far more relevant.
Client / Service Unity
The number of APIs/services is only one variable that can lead to very different thought processes and requirements for API design and architecture. Another is how closely aligned your clients are aligned your services.
All of these functionalities are coming from different services, which have evolved over time, with different authentication strategies, different data formats, and two different systems might share a name for a resource even though they’re conceptually different.
Not only do you have a web version of this, but you have an iOS and an Android version too. In this situation, building BFFs or something similar is fairly common. In that BFF article they talk about building different APIs for different clients, but building an API for a group of very similar clients is common practice.
You can abstract all of the ad-hoc logic in the various systems. Insulate clients from upstream changes. Create cacheable aggregate resources on the BFF comprised of bits of data from multiple other sources.
When you have an API that is closely aligned with the interests of your clients, then build relevant hypermedia controls (actions and forms) for those clients is easy. Abstracting functionality into the API makes the client into a dumb frontend instead of a struggle where frontend developers are having their lives ruined by a team of backend developers they’ve never spoken to.
That’s a big job for many teams who just want to have their smaller “API Team” build one API to do everything and all client teams integrate with that.
These differences make it absolutely impossible to have a discussion about anything in API design being “better.” There are only solutions to problems that you may or may not have (yet.)
Being able to consider things like this is important, and when you’re reading that article about how some giant company do things, probably consider the needs of your own situation a little more carefully.
Tough Things Become Easier Over Time
That said, a lot of concepts that people think are really hard are becoming easier over time.
For example, marking URIs as deprecated used to be really tough to think about, and most companies rolled their own in-house solutions. Now this stuff is easy, just shove a Sunset header in there and sniff for them in the client using faraday-sunset, guzzle-sunset, etc.
With tough concepts getting easier through advanced tooling, stuff that seemed unreasonable for smaller teams to attempt is becoming more viable.
Revisit certain issues over time, and keep an eye on this blog to learn how to do stuff that used to seem confusing.