Let's pretend you're building a software product. Great! Any product of reasonable complexity is going to communicate with another computer type thing at some point. For an Internet enabled product that's usually a server and a client, though it could also be a gigantic microservice architecture with dozens of components. Either way, they communicate with each other through an API.
What is an API anyway? It stands for Application Programming Interface. It's the part of an application that let's other applications talk to it, in other words, it's the UI for other computers. And just like UI for humans, it should be designed.
Now, you're a smart person, so you're probably thinking "If only computers are talking to it, then why should it be designed? Why can't it just be thrown together quickly then relegated to some dark basement?" That's a great question. Yes, a computer will be using it, but humans are still responsible for writing the code that powers the API, and if a human can't make heads or tails of an API, then the interaction between client and server will be messy at best, a catastrophe at worst. Further, a poorly made API can destroy schedules, or even cause unintentional harm to the service's data.
We can do better. Let’s use some Design Thinking to do just that.
Applying design thinking
One of the most prolific designers in history, Dieter Rams, put out 10 principles of good design. Six of those can be applied to APIs:
- Making a product useful
- Making a product understandable
- Thoroughness down to the last detail
- Uses as little design as possible
- Is long-lasting
Let’s dig into these a bit. Aesthetics is easy for APIs. Spell check your API endpoints, please. Pick a naming convention and stick with it (first_name or firstName, not both!), and don’t use unconventional spellings for common words or phrases.
Good design makes a product useful and understandable. People should be able to use an API without having an expert-level understanding. For example, I can use the Slack API without needing to know how their queuing system works or knowing if they’re using a Relational Database or NoSQL. I shouldn’t need to have three conversations with some architect to know how to properly format a request to it.
Good design is thorough down to the last detail and as little design as possible. This doesn’t translate to a lesser amount of work. In fact, it’s quite the opposite, but it pays off.
Pen before pixel
We have a saying at Tallwave, “Pen before pixel.” We actually get out a pen and pad and start sketching and iterating (check out Inkwell). When you get ideas onto paper things you didn’t initially think about will come out. Sketch out model structure, relationships, URL scheme, process ﬂow, and so on. Don’t spend too much time - it’s a sketch, not a sculpture. Get messy. Collaborate. Bouncing ideas oﬀ each other will make new ideas emerge. And don’t be afraid to call out your bad ideas.
Take what emerges from the sketches and turn it into a plain-text document. We’ve taken a liking to the Swagger document spec, but there are others too.
I know you’re thinking “That sounds like a lot of work!” Fair point. And yes, it can be. But when you actually dig into the process and look at the long tail, it actually saves quite a bit of time and headache. When you jump right into code you tend to go down the path of least resistance, which usually leads to a dead end, requiring a lot backtracking and re-work.
When you start with just a blueprint (putting pen before pixel), you’re able to better identify necessary changes before coding starts. Since you’re just operating with plain text, more options open up to you. Branch and try out crazy ideas, iterate, collaborate, file pull requests to review, and discuss everything. That’s what “thorough down to the last detail” means.
When you’re building an API, things will change a lot. Once it’s launched though, you want to avoid changing it. Therefore, write the client code ﬁrst. Yes, really. The UI often informs the underlying model. Here’s a common scenario: You’ve coded an awesome database, service layer, and an API on top of it, and next you get to work on the client codebase. Shortly into that, you encounter something you didn’t quite think through and have to change substantial portions of your backend. Frustrating. To quote my main man Helmuth von Moltke, “No battleplan ever survives contact with the enemy.” Or for something in the 21st century:
There is no bigger risk than building a mobile app against a web service that is under construction. This is like trying to build a house on a plot where another team keeps coming in and tearing up the foundation again. Random changes to the web service, or regressions, will catastrophically consume your budget. — Daniel Pasco, CEO Black Pixel
The good news is writing the client first is possible because there are tools to stand up a mock server based on swagger documentation. This means that you can build a client app that uses that API right away. Then once everything is figured out, you may actually write out the back-end.
Keep in mind, you rarely have all the information you need to build everything up front, but if you follow the process of sketch - document - client - server, changes are much easier to make and you’ll end up with a stronger, well-designed, long-lasting API.
Written by Tallwave