The Hard Things about Naming Things
Using familiarity, identity, and consistency to pick the right names for API operations
I was involved a while ago in the process of designing a new API operation. Along the way, there was a moment when I had to decide what name to give it. What were the key factors I considered when deciding on the new name?
This article is brought to you with the help of our supporter, Scalar.
Scalar is a suite of powerful & customizable developer tools to help you at all stages of API development. Create beautiful API Documentation in a notion-like editing experience.
A part of my work includes designing new operations, data types, and attributes for query languages. A recent episode made me remember something that happened a while ago while I was doing a similar thing but for APIs. What I find interesting is the similarities between the process of naming operations for a query language and an API.
Going back to the project I was working on when designing a new API operation, I remember there were plenty of opinions on how you should name a new operation. However, most of the discussion was centered around technical details. Not the ones I was interested in, for sure.
During a discussion of this nature, when you ask someone how you should name an API—or any other type of programming—operation, you'll get answers related to the morphology of the name, not what the name conveys. Opinions during those conversations are usually related to using singular or plural words, using PascalCase
, camelCase
, or some other combination, and even if the name should be a noun or a verb.
I went over more than 4,000 API definitions1 using OpenAPI to understand how people name their operations. After analyzing all those thousands of API definitions I obtained almost 100,000 unique operations. The ratio of operations per API is above 22, meaning that, on average, each API has that number of operations.
Now, you could do all types of analysis on those 100,000 operations. You could, for instance, determine that around 14% of operation names are written in camelCase
, or that approximately 2% are verbs. But that's not the point. Yes, you'd know how people managing other APIs are naming their operations. However, you wouldn't be able to extrapolate that information into something actionable to your specific scenario.
So, what are the rules I use to help me decide on how to name a new operation? Let's start with one that's related to a developer's ability to use the new operation immediately: Familiarity. Because learning new things is hard, the more familiar the new operation name is, the easier it is for developers to understand it. Jakob's Law, named after the Designer Jakob Nielsen, recommends the usage of familiar patterns—in our case, the operation name—because users don't have to think to be able to use them. In fact, Nielsen even says the more original you try to be, the worse the experience will be.
With this first rule in hand, I would do an analysis of similar operations to see what their names are. If I see that there's a pattern in the naming I'll try and follow that pattern. Now, this is a good way to use those 100,000 operations I obtained before. Let's do a quick exercise to see how other people are naming their operations. Suppose we're creating an operation to let users subscribe to a topic and then receive notifications. How would you name this operation?
Of those 100,000 operations, about 1,000 are related to subscriptions. Many of those operations have names that include the word "subscribe," while others include the word "subscription." Of the many variations of operations only about one-third are actually related to creating a subscription. There seem to be three variants with the highest prominence: createSubscription
(both in camelCase
and PascalCase
), subscribe
, and subscriptions.create
. While subscribe
sounds like the right name for the operation, perhaps it can be confused with something else, especially if you have many things users can subscribe to.
To help fix the problem of having names that can mean different things, there's a second rule I follow: Identity. The goal now is to disambiguate the name by making it clear what it refers to. Following this rule, it's better to use a name that's never been used before than to try to fit an existing one into a new operation. In our case, we can augment the meaning of the word "subscribe" by adding more context to it. The name of the operation could be something like subscribeToTopic
or topic.subscribe
where topic
could even be replaced by the actual identifier for a real topic.
As you notice we still have two options to choose from. The operation name is now clear to understand and familiar to developers who are used to other similar operations, but we still don't know which option to pick. That's when I follow a third rule: Consistency. The goal now is to be consistent with any other naming conventions your company uses. In our specific case, suppose other operations have names such as createUser
, or updateArticle
. Then the option subscribeToTopic
would seem the adequate one. On the other hand, your organization can follow the approach of naming operations by appending an action to a noun, as in user.create
or article.update
. In this case, it's preferable to use the topic.subscribe
name.
As you can see, the real hard things about finding the right name for a new operation are often not related to the format of the name. In fact, that can be easily solved by following the consistency rule as I showed above. To me, the hardest thing is finding a name that fits with all the three rules I follow. That's a name that is familiar to developers, clearly identifies the operation and prevents it from being misunderstood, and finally, aligns with the naming practices your organization follows.
The APIs I analyzed are available on the APIs.guru openapi-directory
GitHub repository.