You probably write bad APIs.
I’m not saying that to be offensive or inflammatory. I’m saying it because writing good APIs is really hard. Like really, really, ridiculously hard. Take a couple seconds to count the number of APIs you have used that were intuitive and easy to work with. My list fits comfortably on one hand: Stripe, Twilio, and v2 of Sendgrid’s mail API. So you probably don’t write good APIs. If you did, my list would be a whole lot bigger.

Really, Really, Ridiculously Hard.
Not that I’m any better myself. I’ve written my fair share of bad APIs. Hell, a few of them would probably make you wish you had a punching bag in the office. But I’ve been making a serious effort to improve for a while now. And the thing that has made the most difference in the quality of my APIs is writing them with the user in mind.
Writing anything with a frontend and backend is a lot like dancing. It’s a beautiful, beautiful thing when both partners are in sync. And it’s a painful, horribly awkward thing when they’re not. When you’re getting started building a new API, it can be tempting to dive right in and start coding. Don’t.
Before you write a single line of code you need to get in sync:
1. Don’t start working until you understand what the end user is trying to do. That means looking at the designs for whatever you’re programming an API for. The whole purpose of the frontend is to drive your app’s UI. By learning the ins and outs of the UI you’ll learn your partner’s half of the dance. At Krit, we always:
- Go over all the ways a user can interact with the application and map out flows. We have the whole team do this. It’s a good way to roadmap a project and get everybody on the same page about what we are building.
- Participate in design critiques. It’s a good way to get familiar with the UI. It’ll also give you the opportunity to ask questions about any design elements that might be unclear. And it usually has the added benefit of making the critique more valuable for your designer(s) because you’ll come at it with a different perspective.
- Look at the wireframes/mockups as you’re planning your API. It’ll help put what your building in context. Working closely with your designer throughout the project will save everyone headaches.
2. Keep your actual user in mind. It’s not the guy or gal that visits your website or opens your app. It’s the guy or gal that’s using your API. The difference is subtle, because they’re trying to achieve the same thing. But your partner doesn’t have a nice, intuitive GUI to work with, so you’ll need to do the best you can to teach them your half of the dance. That means:
- Using the same terminology they use to communicate with the user. A ubiquitous language if you will.
- Talking to them about how you plan to implement things before you actually implement them. This will give them a chance to correct any misunderstandings you might have (it happens to the best of us) and let you know about any limitations on their end that you might have to work around.
- Writing, and maintaining, good documentation.
- And working around any limitations they might have. Ember for example, has trouble tracking changes to objects inside of a dictionary. So if you provide data that way your partner is going to have to do extra work to make it work.
Doing all of those things doesn’t guarantee that your dance will be beautiful. But it does mean you won’t be stepping on your partner’s feet from the get go, and that is a great way to start. A great way to finish, is to be just as mindful of your partner during the dance.
As you program, you need to stay in sync.
1. Keep in mind that you’re really writing two separate things. You’re writing a program that does XYZ, and you’re writing an interface for somebody who wants to do XYZ but doesn’t need to know how you do it. The implication being that you should:
- Keep the two separate. A great way to do this to keep your business logic in your domain models and have your interface act as an orchestrator, that knows what needs to be done at the application level, and coordinates the domain models to do it. It’ll make both pieces easier to reason about, which will make them easier to write and easier to debug.
- Keep your interface thin. If you’re keeping your interface and your domain models separate enough, your interface will be pretty small. A good way to tell is by asking yourself if your interface has any state reflecting business logic. If it does, the two aren’t separate enough. Remember that the only job the interface has is to coordinate, so if it has state it should relate strictly to the progress of a task it was asked to do.
- Look at the wireframes/mockups as you’re writing your API. It’ll help keep the interface that you’re building in context.
- Don’t let your interface leak implementation details. If your partner has to be aware of implementation details to use your interface it slows them down. And perhaps more importantly, it makes it really hard to change those implementation details because it means you’ve got to update code in two places instead of just one.
This is one of the trickier parts of this blog post, and it is worth noting that if you want to do it well, there are a whole books on the topic. Eric Evans wrote an excellent book about it, and I highly recommend reading it. More importantly DHH and Martin Fowler highly recommend reading it.
2. If you have to make any changes to spec, run them past your partner. Changes happen, changes will happen on the frontend too. The key to dealing with them is to talk about them and stay in sync.
Making a ballroom dance look elegant and effortless is incredibly difficult. On the rare occasion that you see two people make it happen, it was years in the making. Thousands of dances went into making the performance you saw perfect. Programming is the same way. The only way to get better is to practice. You might not be able to do all of these things the next time you write an API. Maybe you’ve got a tight deadline for another project and you can’t afford to take time out your schedule to participate in the design critiques. Maybe you’re client has a super small budget and you can’t afford to take the time to write, and maintain quality documentation. But if you do as much as you can you’re API will be better for it. And if you keep doing more and more each time, you’ll write a great API someday; I guarantee it.