Hyrum’s Law says: With a sufficient number of users of an API, it does not matter what you promise in the contract: all observable behaviors of your system will be depended on by somebody. But by itself it’s not all that helpful to me. It’s like saying, “with a sufficient number of people, a room will be overcrowded.” Is that according to Fire Marshalls? Introverts? How big is the room?
Leonard Richardson gave a talk back in 2016 called The Magic Arrow. He shared his experiences building a mobile application for the New York Public Library that allowed the patrons to borrow and read ebooks. He found there were characteristics of architectural designs that made them more extensible and reusable, and he summed them up under the idea of the magic arrow. When we draw architectural diagrams, we draw boxes and connect them with arrows.
What if we could combine the power of HTTP with the universal qualities of URLS to create a way to build an API that works like code? It would be a way to turn the web into a programming language of sorts, to treat an API as if it were code. To explain this weird idea, we’ll think about it in terms of calling functions with HTTP calls similar to how you’d call functions in code.
When we design an API—among many things—we’re designing how we think the API will change. We often reach for versioning to handle this, but versioning is a small part of the change discussion. For instance, will the versions be for the entire API or for individual resources? Will we support each version forever, or will we deprecate and sunset all or parts of versions? And at what point do we switch to a new version?
I recently shared how a team I worked on designed an API using code. The goal was to show that code can be used as a tool for design, and how prototyping can give us fast feedback on the quality of our design. In this writeup we’ll look at how we might use code to design API behavior. We’ll use Python and FastAPI like we did in the last writeup, so you may want to read it first before moving forward.
I was on a team that needed to design a new API. As a Design First team, we’d normally start off with an OpenAPI file. But this time we started with some code. We opened up our IDE, created a Python file, and started coding models and endpoints. It might seem like we switched to a Code First approach since we started with code. But this wasn’t the case for us.