Better Programming

Advice for programmers.

Follow publication

Semantically Inflect Your API Routes

Why all plural is all wrong

Cheth Rowe
Better Programming
Published in
11 min readMar 25, 2022
Preschoolers recognize noun inflection errors; grown-ups should too. (When specifying thing #3, there is no “s”. ) Image credit: Author

Ambiguity. Programmers too often find ourselves rewriting code because “requirements” prove misleading, possibly misinformed — sometimes describing something altogether different from what the stakeholders meant. Communication between people is hard. Developers accept that; we rewrite; the software creation cycle spins forward. Communication between computers should work better. Yet numerous recommendations for API route naming enshrine that very same bugaboo, ambiguity.

Exhortations to “use plural everywhere” foment confusion. As does “use singular everywhere”. Both approaches overvalue a commendable desire for simplicity, overlooking the resultant long-term technical debt of lost semantic opportunity. The solution is so simple: properly use the letter “s”.

The frontispiece, with its preschool alphabet blocks attempting route /things/3, demonstrates. What should this route represent? (any) 3 blocks? any block displaying the number 3? third block from the sun? The answer should be: none of the above. This route is both syntax violation and semantic failure. It took me a while to understand why.

Ye Olde Precedent

Our shop forbids plural table names. Fine by me. Singulars deliver [1]. Plural names would have been fine too. Throughout my career, in multiple singular and plural shops, I never encountered usability difference; both approaches work, nearly equally well [2]. For table naming, my sense is that having a standard is far more important than which standard.

For route naming I expected some equivalent direction, but found nothing. Our thoughtfully compiled shop standards [3] made no mention of any aspect of Application Programming Interfaces (APIs).

I doubt I am alone. Perhaps table naming rules are inherently simpler than route naming rules, so more likely to be written. Perhaps more people learn CREATE TABLE than learn how to wire endpoints. Perhaps more shops need databases than need custom APIs. Whatever the reason, at least in my experience, API shop standards are rarely encountered.

The floundering programmer (reveling in that expanse before understanding) looks for clues. How did this omission occur? One might entertain the timeline possibility: perhaps databases have been around longer. Perhaps not. Mainstream programming has thoroughly embraced relational databases for nearly half a century, beginning shortly after E.F. Codd’s seminal 1974 paper [4]. Six years prior, a 1968 conference paper on computer graphics introduced the term “Application Program [sic] Interface” [5]. The idea, the underlying concept of APIs, their raison d’être — standardized processes — began decades earlier, born in the glow of the vacuum tube computers of the 1940s [6].

Perhaps our standards authors simply thought they had it covered, that the same “no plurals” rule applied equally well to databases and routes. It is a widely held belief. My exploration of the fallacy of this seemingly logical conclusion expanded into this document.

Total Rebellion

My exploration began as a task to build an API. I had written APIs for several previous employers, so I was sure I knew all about it. Turns out, for a system exceeding one hundred endpoints, query string parameters prove insufficient. Routes sprouted.

Initially I undertook the same-as-database approach. I obeyed the repeated admonishments to eschew plurality. When I read, “Database names should be singular”, I believed the plural prohibition applied to routes by extension, by logic, by precedent.

This worked for a while. Except my all-singular, standards-compliant routes sprang usability issues and ambiguity. The leaks became too big. I tried alternatives. I went full-on opposite: I tried all plurals, consciously violating shop rules. Total rebellion was fun, and amazingly successful — for a moment. All my initial issues disappeared; unfortunately just as many new ones arose. I tried ignoring the problem (as though that would work).

In frustration (or inspiration) I reverted to a more fundamental set of syntactical standards, pre-kindergarten plural nouns: singular noun for one item, plural nouns for the bunch. It worked, perfectly. Observing preschool plurality rules [7] resolved every ambiguity. This time at the cost of guilt and worry. To ward off imagined future admonishments (or worse) about workplace rebelliousness, I readied an explanation: the rationalization that “should be singular” did not specifically single out routes. Weak is an understatement.

Programming is Not a Science

Query filenames in a singular shop
— — — — — — — — — — — — — — — — — -
get_thing_x.sql (Yes!)
get_things.sql (plural violation)
get_my_things.sql (plural violation)
get_all_things.sql(plural, ambiguous, and redundant)

Knowing I needed better, I reached for science. I ran a thought experiment: routes are often database queries in disguise, so what would be logical filenames for a set of route-like queries? For a specific row, get_thing_x.sql looked perfectly acceptable, all singular. For every multiple row query, the filename test failed. Plurals every time. Total shop standards violation.

Unconvinced by experimental results (and unconvinced that programming is sufficiently scientific to rely on experiments), I searched for better answers.

The usual supplier of better answers, the web (on programming issues, perhaps), struggles to satisfactorily answer this question, instead presenting multiple, highly-ranked, well-reasoned, and strongly conflicting arguments [8]. The discussions traverse beyond singular or plural.

There has always been a third way, a mixture allowing both plural and singular, just generally not by design. In the database world, most shops forced to carry both singular and plural table names blame legacy technical debt; few endorse such agglomeration.

Embrace the Non-Binary

Routes are different. They act. (More correctly, endpoints act; routes merely identify the target.) Tables store data very well; but doing something useful with that data generally requires external code; doing is not the point of databases. In contrast, APIs intrinsically embody doing. Their endpoints exist to perform, their super powers flying further than any table, triggering tweet storms, slewing telescopes, analyzing DNA. It should not surprise that table naming conventions prove insufficient.

Unlike databases, where opinions essentially bisect — a slight majority preferring all singular table names, while the remainder extol plural — route naming trisects three possibilities. Unlike tables, the route naming majority prefers plural nouns [9]. This best practices disconnect between singular tables versus plural routes is informative. It acknowledges the old rules do not apply. It reveals perhaps the most salient route-naming divergence, the inclusive non-binary. Unlike databases, route naming legitimately empowers a third way, supported by a smaller, but rather enthusiastic cohort: plurals and singulars “as appropriate” [10].

Rather than demand conformity, add semantics.

Not where I began.

What Else Will Go Wrong?

All plural examples
— — — — — — — — —
GET /things (get every) (Yes!)
GET /things/3 (get #3) (poor English grammar; ambiguous;)
GET /things/all (get every) (redundant; DRY violation;)

The majority preference for all plural routes starts so well: GET /things works. That is its only success. It promptly fails, casting routes returning one item as uncouth abusers of English grammar, “Get one things [sic]”. Unacceptable. Programmers strictly observe every syntax rule for every language within our purview. Except English.

Our tl;dr world shares blame; it encourages some disregard for formality; but throwaway text message shortcuts are no excuse for intentionally designing worry-inducing routes. APIs should plan for the longer timeframe, for the needs of future users. Explicitly demanding ingrained syntax violation deserves distrust, “What else will go wrong?”

Antipattern All

Some who recommend all plural, go overboard on the all concept, using that very word in the route. “All” is an antipattern. Although it may seem intuitive, it is not helpful. Rather than adding information, “all” seduces route authors into occult redundancy, treating the word as a magical abracadabra, invoking GET /things/all. Most, presumably correctly, interpret that endpoint as “send every row”. However, stating plurality twice, “things” and “all”, is nearly as bad as a double negative. “Don’t Repeat Yourself” deserves its status as programmers’ mantra [11]. Specify plurality once: GET /things.

Singular Is Even Worse

All singular examples
— — — — — — — — — —
GET /thing/3 (get #3) (Yes!)
GET /thing (get every) (poor grammar; ambiguous;)
GET /thing/all (get every) (poor grammar; magic word; ambiguous;)

The minority preference for all singular routes, the scheme I tried first, fares worse. It either requires the already castigated magical “all”, with its grammar violation, “all thing [sic]”, or magically redefines singular “thing” into suddenly encompassing everything. Equally unacceptable. Proponents frequently cite their existing singular table naming standard. Repositioning standards does not always work.

Debtors Detour

Technical debt hangs over programmers, threatening to derail our days, our sprints, our lives. Poor route names create more technical debt. Months later, years later, when some new hire tries to use your routes, what will they intuitively expect for noun plurality? (Even if they RTFM.) Ordinary English. “Get (all) thing [sic]” will not be first choice. The old days of all caps vars and three character op codes are over. We can afford more informative code.

Maintenance may be the biggest expense in software development. Ambiguous routes cost real dollars.

As You Already Know

As appropriate examples
— — — — — — — — — —
GET /thing/3 (get #3) (Yes!)
GET /things (get every)(Yes!)

Matching plurality “as appropriate” solves grammar issues. More importantly, it increases understandability. No ambiguity. The “as appropriate” approach is intuitive, easy to explain and comprehend: when targeting a specific object, use singular; when targeting a collection, use plural [12].

“As appropriate” is great; but the term is lacking. The formal name for modifying (inflecting) words to distinguish between singular and plural is: noun number inflection.

Inflection Rules (You Already Know)
— — — — — — — — — — — — — — — —
IF singular THEN suffix = NULL
IF plural THEN suffix = “s”

If the noun is singular, the inflection is NULL, no suffix; If the noun is plural, the inflection is the appended morpheme “s”. This simple rule is prominent in English (and increasingly common within routes).

Amusing exceptions do not change the programmatic usefulness of this simple pre-K rule.

Irregular Entertainments

“People”, “mice”, and “data” exhibit English’s penchant for illogical, or at best non-obvious, morphology. While most English nouns achieve plurality by appending “s”, deviants abound. Occasional irregularity propels some route authors to avoid plural nouns entirely. This is a poor argument. Choosing an irregularly inflected noun more often indicates an earlier design flaw.

Noun choice matters. Rather than person/people choose something more informative, more specific: customer/customers, user/users, citizen/citizens. If you must, coin your own plurals, “persons”, “mouses”, “datums”. Users of such artificially-inflected route names may chuckle; but they will understand the intent. Pluralized for all.

“Murder” is unwise. This term for a plurality of crows is largely poetic anyway. Animals — perhaps because our ancestors considered them commodity, a singular concept, rather than unique individuals — dominate lists of irregular plurals [13]. Our animal nature may even explain the irregularity of person/people. A few irregular plurals are not reason to murder intuitive simplicity: singular for one, plural for all.

Singular and Plural (and Superman)

The semiotic letter “S”, famously emblazoned on the chest of his costume, does not actually stand for “Superman”. According to (revisionist) comic book lore, it is a Kryptonian symbol of hope for a better tomorrow [14].

“Tomorrow”, of course, would be (another) poor choice for route noun, partly because of its ambiguous plurality. It can mean either the single day after today, or a long, indefinite future (unjustly denied planet Krypton).

Semantic routes merit the same “s”-sparkled symbolism; they make tomorrow better. Future programmers may not thank you; they may not even imagine the possibility of anything as crude as all plural. Perfectly fine. The best systems do not draw attention; they just work.

Routes are rather like Superman: faster than rewriting SQL every time, more powerful than any table, able to leap many queries in a single bound. When you name them well.

References and Notes

[1] I. Mackinnon, Table Naming Dilemma: Singular vs. Plural Names (2017). Retrieved from stackoverflow.org: https://stackoverflow.com/questions/338156/table-naming-dilemma-singular-vs-plural-names. “I prefer to use the uninflected noun, which in English happens to be singular.”

[2] To be picky, singular table names offer two, generally minor advantages: the trivial, one less character to type; and the not necessarily trivial, aligning with the slight majority preference of the larger professional world for singular table names.

[3] Name Withheld, Standards and Conventions (2016). “Database names should be singular…Table names are singular…Column names are singular.”

[4] E. F. Codd, A Relational Model of Data for Large Shared Data Banks (1970). Explanation for the continuing popularity of all singular table names begins with the master. E. F. Codd used singular table names exclusively in his seminal description of the relational model.

[5] I. Cotton, F. Greatorex, Data structures and techniques for remote computer graphics (1968). Retrieved from https://dl.acm.org/doi/10.1145/1476589.1476661. Believed to be first published use of the term “Application Program [sic] Interface”.

[6] N. Metropolis, History of Computing in the Twentieth Century (1980). Credits David J. Wheeler with constructing the world’s first application programming interface in 1949 while a graduate student at Cambridge. Wheeler’s term was “coordinating orders”.

[7] S. Kouider, J. Halberda, J.Wood, S. Carey, Acquisition of English Number Marking: The Singular–Plural Distinction (2006), Retrieved from https://www.harvardlds.org/wp-content/uploads/2018/05/Kouider-et-al..-2006.-Acquisition-of-English-Number-Marking-The-Singular-Plural-Distinction-copy.pdf. States, “tests on these subsets revealed that 36-month-olds succeeded on -S singular and plural trials”

[8] J. Au-Yeung, R. Donovan, Best practices for REST API design (2020). Retrieved from stackoverflow.org: https://stackoverflow.blog/2020/03/02/best-practices-for-rest-api-design/. The authors state, “Name collections with plural nouns”. The many commentors express a wider range of opinions.

[9a] J. Au-Yeung, R. Donovan, Best practices for REST API design (2020). The author’s admonishment, that all routes use “plurals to be consistent with what’s in our databases,” apparently assumes everyone has tables with plural names.

[9b] M-Way Solutions, 10 Best Practices for Better RESTful APIs (2014). “Do not mix up singular and plural nouns…use…plural nouns for all resources.” I disagree.

[9c] Y. Katz, A SPECIFICATION FOR BUILDING APIS IN JSON (2013). Retrieved from jsonapi.org: https://jsonapi.org/format/#fetching-resources. This open source project requests plurals for all route “types.” It posits routes like, “GET /articles/1”. My read is that “Get articles [sic] 1” is unacceptably poor English.

[10] L. Lustig, Best practices for REST API design (2020). Retrieved from stackoverflow.org: https://stackoverflow.blog/2020/03/02/best-practices-for-rest-api-design/. Lustig’s comment on Au-Yeang’s article argues, “singular/plural [route names] should be determined by whether the endpoint returns a single object or a collection.” This backwards logic is true, as long as single record (or empty) collections do not short circuit plural routes by returning an object.

[11] A. Hunt, D. Thomas, The Pragmatic Programmer: From Journeyman to Master (1999). Introduces the DRY principle with a story: “Giving a computer two contradictory pieces of knowledge was Captain James T. Kirk’s preferred way of disabling a marauding artificial intelligence.”

[12] More accurately, one specific record. Requests for a non-specific record should use plural with a query string limiter.

[13] F. Toupin, About Plural Morphology and Game Animals: from Old English to Present-Day English (2015). Retrieved from https://journals.openedition.org/lexis/964. Discusses the “ psychological salience of game animals in Anglo-Saxon culture…”.

[14] M. Waid, Superman Birthright: The Origin of the Man of Steel (2005). Introduces the deeper meaning of “s”.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Cheth Rowe
Cheth Rowe

Written by Cheth Rowe

programmer, pianist, and improvisational instantiator.

Responses (2)

Write a response