Don’t call your API Ishmael.

I can think of a number of reasons not to name your API after the narrator of Moby Dick, and I’m sure you can too. But deciding what to name your API is not all that easy; in fact, it’s said to be one of the two hardest problems in computer science (the others being caching, and off-by-one errors.)

Start with the basics

For a typical RESTful API, the basic rules of naming are fairly straightforward. Give your routes names which are plural nouns which correspond to the resources in your domain, so that you can use HTTP verbs to manipulate collections and singular instances of those nouns. If you are starting a book store, for example, this rule results in routes like:

POST /events // Create an author-signing event.
GET /authors // List all of the authors whose works are available in the store.
PUT /books/{isbn} // Update the details for a single book.
DELETE /orders/{orderId}/books/{isbn} // Remove a book from an order.

… and what have you. It’s an enchantingly simple scheme which works really well when your API acts as a simple interface on top of your database. Once you’re on this path, make sure to follow best practices for RESTful design.

Search for the perfect name

Of course not all APIs serve as database interfaces. An important API use case is search. How do you name the routes for a search API? At first blush it looks pretty easy:

GET /books?query=woolf // Find all books matching the query

The problem here is that the semantics may not match the user’s intention. Does the user want books with “Woolf” in the title - for example, biographies of Virginia Woolf? Or might the user be looking for books by Virginia Woolf? Or perhaps the user actually doesn’t want books at all, but is actually looking for a lecture event that’s about the works of Virginia Woolf?

You could of course design APIs to match each of these use cases - GET /authors?name=woolf, GET /events?query=woolf, and so on - but the problem with search is that the API client itself is often ignorant of the user’s intention, and the server must decide what the best response is from limited information. Think about the Google search UI for a minute. It takes as input a single string of text, and can turn around and do everything from currency conversion to airline booking.

There are a few possible solutions here:

  • Stick with the GET /books?query={searchTerms} name, and accept the fact that not all results from this route will actually be books.
  • On the pretense of loyalty to the routes-are-resources idiom, use a big compound noun: GET /booksOrAuthorsOrEvents?query={searchTerms}, - or take that to its logical conclusion and use GET /anyResources?query={searchTerms}.
  • Dedicate a route to search; I’ve often seen this approach executed as GET /search?query={searchTerms}. For example, Bing’s search API follows this pattern.
  • Define searches as a special kind of resource, and let users create them via your API: POST /searches, with the search terms in the body.

I’m not sure I like any of these approaches all that well. The first approach is simply misleading to consumers. The second strikes me as particularly odious and difficult to understand. The third is popular but a poor fit with RESTful semantics, since “search” is not a noun.

I happen to like the fourth approach best, since it follows the noun-verb idiom well. As a side bonus, it uses the POST verb, which is a more natural fit for larger request bodies and advanced search options. For example, if the engine allows search by author’s last name, a typical query might be:

POST /searches
{
  “author”:{
    “lastName”: “Woolf”
  }
}

It’s certainly possible to do something similar in GET - for example, GET /search?author.lastName=Woolf - but that approach becomes unwieldy for the consumer very quickly, and it poses annoying deserialization problems for the producer right away. The POST approach is much more extensible.

Add it up

A less-common, but nevertheless important use case for APIs is calculation: consumers want the service to do some math for them. Typically these scenarios arise when the server uses some proprietary information in its formula, or when the formula itself is proprietary or too complex for the consumer to do itself.

There are some simple calculations with obvious naming schemes. For example, suppose we want our bookstore to calculate shipping costs for an order before we finalize it. Such an API might look like: GET /orders/{orderId}/shippingCosts.

In other cases, we tend to think of the formula itself, or its outcome, as the resource we’re interested in. For example, suppose the bookstore offers a number of discounts on books purchased together, and we’d like to know how various combinations affect the discount. A resulting API might look like GET /discounts?book1={isbn1}&book2={isbn2}. It’s possible, of course, to deliver equivalent functionality using existing routes - you can imagine putting these two books into a single order and then requesting GET /orders/{orderId}/discounts - but the /discounts idiom more naturally fits the end user’s thought process, and is probably a better fit for the client as a result.

It’s possible to use the same trick here as with search results: GET /discounts can quite readily become POST /discountCalculations. Unless there’s some really compelling reason, though, I think such an approach only confuses consumers, who don’t think of calculations in terms of collections, the way they probably do think about searches. Also note that the POST resource has a considerably more awkward name.

If the line between calculation and search looks gray, that’s because it actually is. Search is a kind of calculation, albeit a very complicated one, and some calculations are really just searches for the optimal answer. Take this line of thought to a logical extreme and you get Wolfram Alpha, a calculator masquerading as a search engine, whose API looks a lot like Bing’s.

Listen to your consumers

We’ve really only looked at a handful of API use cases here: there are many others, each with quirky naming problems of its own. The key to a good naming scene is really to listen to your consumers. What names and idioms make sense to them? How will they be using the api? Ultimately, the best API names are those which make the most sense to the developers using them.

And don’t make the mistake that names are unimportant, either. Imagine starting a coffee chain with an obscure literary name - and choosing a name that just doesn’t sound very appealing, like Ahab’s. It could be a very expensive mistake.

Image courtesy of Natalie Collins