Plural vs Singular Resource Naming in REST APIs

Should your REST API use /pet or /pets? This seemingly small decision affects consistency, readability, and developer experience. Learn why plural naming wins.

TRY NANO BANANA FOR FREE

Plural vs Singular Resource Naming in REST APIs

TRY NANO BANANA FOR FREE
Contents

One character. That's the difference between /pet and /pets. Yet this tiny decision has sparked endless debates and broken countless APIs.

Should you use singular or plural resource names in your REST API URLs? The answer affects every endpoint you build, every client you support, and every developer who uses your API.

Let's settle this debate with evidence, not opinion.

The Case for Plural

Most modern APIs use plural resource names. GitHub uses /repos, Stripe uses /customers, Twitter uses /tweets. There's a reason for this consistency.

Reason 1: Collection Semantics

REST APIs work with collections and individual items. Plural naming reflects this reality:

GET /pets           ← Returns a collection of pets
GET /pets/123       ← Returns one pet from the collection
POST /pets          ← Adds a pet to the collection
DELETE /pets/123    ← Removes a pet from the collection

The URL structure makes semantic sense. You're working with the "pets" collection, whether you're accessing all items or one item.

Compare this to singular naming:

GET /pet            ← Returns... what? One pet? All pets?
GET /pet/123        ← Returns one pet
POST /pet           ← Creates a pet
DELETE /pet/123     ← Deletes a pet

The singular form creates ambiguity. Does GET /pet return one pet or all pets? You need documentation to clarify.

Reason 2: Consistency Across Operations

Plural naming keeps your URLs consistent across all HTTP methods:

GET    /pets       ← List all
GET    /pets/123   ← Get one
POST   /pets       ← Create one
PUT    /pets/123   ← Update one
PATCH  /pets/123   ← Partial update
DELETE /pets/123   ← Delete one

Every operation uses the same base path: /pets. Developers learn one pattern and apply it everywhere.

Singular naming forces you to switch between forms:

GET    /pet        ← List all (or does it?)
GET    /pet/123    ← Get one
POST   /pet        ← Create one

The inconsistency creates cognitive load. Developers must remember which form to use for which operation.

Reason 3: Nested Resources Work Better

APIs often have nested resources. Plural naming makes these relationships clearer:

GET /pets/123/vaccinations           ← All vaccinations for pet 123
GET /pets/123/vaccinations/456       ← One vaccination
POST /pets/123/vaccinations          ← Add a vaccination

The structure reads naturally: "Get vaccinations for pet 123."

With singular naming:

GET /pet/123/vaccination             ← All vaccinations? One?
GET /pet/123/vaccination/456         ← One vaccination

The mix of singular and plural creates confusion. Is /pet/123/vaccination one vaccination or all vaccinations?

Reason 4: Query Parameters Make Sense

Filtering and searching work naturally with plural collections:

GET /pets?status=available
GET /pets?breed=golden-retriever
GET /pets?age_min=1&age_max=5

You're querying the "pets" collection with filters. The plural form makes this obvious.

Singular naming feels awkward:

GET /pet?status=available

Are you getting one pet or multiple pets? The singular noun conflicts with the plural result.

Reason 5: Industry Standard

Check the APIs you use daily:

GitHub:

GET /repos
GET /repos/{owner}/{repo}
GET /repos/{owner}/{repo}/issues

Stripe:

GET /customers
GET /customers/{id}
GET /customers/{id}/subscriptions

Twitter:

GET /tweets
GET /tweets/{id}
GET /users/{id}/tweets

Shopify:

GET /products
GET /products/{id}
GET /products/{id}/variants

The pattern is clear. Major APIs use plural naming. Following this convention makes your API familiar to developers.

The Case for Singular

Some developers prefer singular naming. Let's examine their arguments.

Argument 1: "It's More Grammatically Correct"

Proponents say /pet/123 reads better than /pets/123 because you're getting one pet, not multiple pets.

Counter: REST URLs represent resources, not sentences. The URL /pets/123 means "item 123 from the pets collection," which is grammatically fine.

Argument 2: "It Matches Database Table Names"

Some teams use singular table names (pet, order, user) and want URLs to match.

Counter: Your API is not your database. The two serve different purposes. Your database schema is an implementation detail that shouldn't dictate your API design.

Many databases use plural table names anyway (pets, orders, users), so this argument doesn't hold universally.

Argument 3: "It Avoids Irregular Plurals"

English has irregular plurals: person/people, child/children, mouse/mice. Singular naming avoids this complexity.

Counter: Most API resources use regular plurals. When you do encounter irregular plurals, just use them:

GET /people
GET /children
GET /mice

Developers understand English plurals. Don't let edge cases drive your entire naming strategy.

Argument 4: "It's Simpler"

Some argue singular is simpler because you don't think about pluralization rules.

Counter: Plural naming is simpler for developers using your API. They learn one pattern (plural) and apply it everywhere. Singular naming creates ambiguity that requires documentation.

The Hybrid Approach (Don't Do This)

Some APIs mix singular and plural:

GET /pet/123        ← Singular for individual items
GET /pets           ← Plural for collections

This is the worst of both worlds. Developers must remember two patterns and switch between them. It doubles cognitive load without adding value.

Never mix singular and plural in the same API. Pick one and stick with it.

Real-World Impact

Let's look at how naming affects actual development.

Example 1: Client Code

With plural naming:

// Consistent pattern
const pets = await api.get('/pets');
const pet = await api.get('/pets/123');
const orders = await api.get('/orders');
const order = await api.get('/orders/456');

With singular naming:

// Inconsistent pattern
const pets = await api.get('/pet');  // or /pets?
const pet = await api.get('/pet/123');
const orders = await api.get('/order');  // or /orders?
const order = await api.get('/order/456');

Plural naming creates predictable patterns. Developers write code faster with fewer bugs.

Example 2: SDK Generation

Tools like OpenAPI Generator create SDKs from your API spec. Plural naming produces better code:

# Generated from plural API
client.pets.list()
client.pets.get(id=123)
client.pets.create(data={...})

# Generated from singular API
client.pet.list()  # Awkward: "pet list"
client.pet.get(id=123)
client.pet.create(data={...})

The plural form reads more naturally in generated code.

Example 3: Documentation

API documentation is clearer with plural naming:

Plural: - GET /pets - List all pets - GET /pets/{id} - Get a specific pet

Singular: - GET /pet - List all pets (confusing!) - GET /pet/{id} - Get a specific pet

The plural form is self-documenting. The singular form requires explanation.

How to Handle Edge Cases

Singleton Resources

Some resources have only one instance per user:

GET /profile        ← User's profile (only one)
GET /settings       ← User's settings (only one)
GET /dashboard      ← User's dashboard (only one)

These are singleton resources. Use singular naming because there's no collection.

Uncountable Nouns

Some nouns don't have plural forms:

GET /equipment
GET /furniture
GET /information

Use the noun as-is. Don't force pluralization where it doesn't make sense.

Actions vs Resources

Sometimes you need endpoints for actions, not resources:

POST /pets/123/adopt        ← Action: adopt this pet
POST /orders/456/cancel     ← Action: cancel this order
POST /users/789/verify      ← Action: verify this user

These are RPC-style endpoints. They're acceptable for actions that don't fit the CRUD model.

Migration Strategy

Already have an API with singular naming? Here's how to migrate:

Step 1: Add Plural Endpoints

Keep existing singular endpoints and add plural versions:

GET /pet/123        ← Deprecated, still works
GET /pets/123       ← New, recommended

Step 2: Update Documentation

Mark singular endpoints as deprecated. Show plural examples in all new documentation.

Step 3: Notify Clients

Give clients 6-12 months to migrate. Send emails, update docs, add deprecation warnings.

Step 4: Remove Singular Endpoints

After the migration period, remove singular endpoints in a new major version.

The Verdict

Use plural resource names. The benefits are clear:

✓ Consistent across all operations ✓ Clear collection semantics ✓ Better nested resource URLs ✓ Natural query parameter usage ✓ Industry standard pattern ✓ Self-documenting URLs

The singular vs plural debate is settled. Modern APIs use plural naming. Follow the standard and your API will be easier to learn, use, and maintain.

Quick Reference

Do this:

GET /pets
GET /pets/123
GET /pets/123/vaccinations
GET /orders
GET /users

Not this:

GET /pet
GET /pet/123
GET /pet/123/vaccination
GET /order
GET /user

Exceptions:

GET /profile        ← Singleton resource
GET /settings       ← Singleton resource
GET /equipment      ← Uncountable noun
POST /pets/123/adopt ← Action endpoint

Want to see plural naming in action? Check out the Modern PetStore API, a production-ready example that follows all REST best practices, including consistent plural resource naming.

Related Reading: - The 7 RESTful Design Principles Every API Must Follow - Stop Using Action Verbs in Your API URLs - How to Write API Documentation Developers Actually Read