Fast Notes on API Design
2022-05-16
An API is a handle on a computer system.
Handles come in all shapes and sizes. The right handle can make a tool a pleasure to use or a total nightmare. Sometimes, in the dead of night, I still remember the metal scissors I used in grade school and how badly my hands had to contort to fit into them.
Anyone who's studied user interface will remember the doors that Don Norman discussed at length in The Design of Everyday Things. More than mere comfort, the right handle makes its function obvious and easy. And likewise, I think we've all encountered the door handle that's so minimalist and avant-garde that the mind boggles at how to even use it. Just recently I spent more than 5 minutes trying to unlock a door I hadn't seen before. With the right trick, it takes less than a second; but if you don't know the trick, it's almost hopeless.
This is what Jeff Atwood calls the pit of success, the magnetic attractor that makes the right thing easy. But what does that mean concretely?
I don't know, but here's what I think. A good API:
- has a reasonable, predictable name.
- easily comports with its user's mental model.
- makes common cases easy and dangerous cases difficult. React's
dangerouslySetInnerHTML
is my favorite example of this. - is as flexible as it needs to be across the problem domain. (This requires thoroughly knowing the problem domain.)
And inversely, a bad API:
- has an unreasonable or unpredictable name.
pandas
is pretty great, but itsread_csv
vs.to_csv
IO functions are a notable example of this anti-pattern. (Better would beread_csv
andwrite_csv
, orfrom_csv
andto_csv
). - has a strange or unusual mental model. This is why stateful operations are often such a slog — they make code that much harder to understand.
- makes common cases difficult and dangerous cases easy. C++ is my go-to example of this.
- is so flexible that it's hopelessly complex, or so basic that it's not usable. Go's interfaces are my go-to example of the frustrations of a too-basic tool.