TL;DR
REST API resource names should be plural. Use /pets/{id} not /pet/{id}. Plural names consistently represent collections, align with HTTP semantics, and match how developers think about resources. Modern PetstoreAPI uses plural names throughout its API, following industry best practices.
Introduction
When designing a REST API, you’ll face the question: should your endpoint be /user/123 or /users/123? This is a common debate among developers.
The answer: use plural. But understanding the reasoning is crucial. Plural resource names fit REST’s collection model, HTTP semantics, and developer expectations.
The old Swagger Petstore used /pet/{id}—an inconsistency that spread the wrong convention. Modern PetstoreAPI fixes this by consistently using plural resource names.
💡 Tip: If you’re building or testing REST APIs, Apidog helps you validate resource naming, test endpoint consistency, and ensure your API follows REST best practices. Import OpenAPI specs, check naming patterns, and catch inconsistencies before release.
This guide explains why plural names are the right choice, how they fit REST principles, and how to implement them—using Modern PetstoreAPI as a reference.
The Plural vs Singular Debate
Both singular and plural seem reasonable at first glance.
The Singular Argument
“When I request /user/123, I’m getting one user. Singular feels right.”
This reasoning focuses on the response—a single resource, so a singular path.
The Plural Argument
“The URL represents a collection. /users is the collection. /users/123 is an item in that collection.”
This focuses on the resource structure—URLs represent collections, and you access items within them.
Why This Matters
Your choice impacts:
- API consistency – Mixed naming confuses developers.
- Mental models – Influences how developers understand your API.
- Code generation – Tools generate code based on resource names.
- Documentation clarity – Docs must explain your structure.
Why Plural Names Win
Plural resource names align with REST and HTTP semantics. Here’s how:
1. Collections Are Plural
Resources are collections. For example:
GET /users ← The users collection
GET /users/123 ← Item 123 in the users collection
POST /users ← Add to the users collection
DELETE /users/123 ← Remove item 123 from the users collection
This is a consistent mental model. With singular names, the logic breaks:
GET /user ← Which user?
GET /user/123 ← Makes sense
POST /user ← Add to... what?
2. HTTP Methods Operate on Collections
HTTP verbs operate on collections:
-
GET /users– Retrieve the collection -
POST /users– Add to the collection -
GET /users/123– Retrieve an item from the collection -
PUT /users/123– Replace an item -
DELETE /users/123– Remove an item
3. Consistency Across Endpoints
Plural naming keeps endpoints consistent:
GET /pets ← Collection
GET /pets/123 ← Item in collection
GET /orders ← Collection
GET /orders/456 ← Item in collection
With singular, you risk inconsistency:
GET /pet ← Doesn't make sense
GET /pet/123 ← OK
GET /pets ← Now it's plural?
4. Industry Standards
Major APIs use plurals:
-
GitHub:
/repos,/users,/issues -
Stripe:
/customers,/charges,/subscriptions -
Twilio:
/accounts,/messages,/calls -
Google:
/users,/groups,/files
Modern PetstoreAPI follows this with /pets, /orders, /users.
The Collection Mental Model
Understanding collections improves API design.
Collections in REST
A collection is a set of resources. For a pet store API:
-
/pets– All pets -
/orders– All orders -
/users– All users
Standard operations:
GET /pets ← List pets (filter, paginate)
POST /pets ← Create a pet
GET /pets/{id} ← Get a pet
PUT /pets/{id} ← Update a pet
DELETE /pets/{id} ← Delete a pet
Sub-Collections
Collections can have sub-collections:
GET /pets/{id}/photos ← Photos for pet {id}
POST /pets/{id}/photos ← Add photo to pet {id}
GET /pets/{id}/photos/{photoId} ← Specific photo
Pattern: collections are plural, items accessed by ID.
Modern PetstoreAPI Example
Modern PetstoreAPI docs implement this:
GET /pets
GET /pets/{petId}
GET /pets/{petId}/photos
POST /pets/{petId}/vaccinations
GET /orders
GET /orders/{orderId}
GET /orders/{orderId}/items
Every collection is plural. Items are accessed by {id} within that collection.
How Modern PetstoreAPI Uses Plural Names
Real API examples from Modern PetstoreAPI:
Pet Resources
GET /pets ← List all pets
POST /pets ← Create a new pet
GET /pets/{petId} ← Get a specific pet
PUT /pets/{petId} ← Update a pet
DELETE /pets/{petId} ← Delete a pet
GET /pets?status=AVAILABLE ← Filter pets by status
Order Resources
GET /orders ← List all orders
POST /orders ← Create order
GET /orders/{orderId} ← Get a specific order
PUT /orders/{orderId} ← Update order
DELETE /orders/{orderId} ← Cancel order
User Resources
GET /users ← List users
POST /users ← Create user
GET /users/{userId} ← Get a specific user
PUT /users/{userId} ← Update user
DELETE /users/{userId} ← Delete user
Nested Resources
GET /pets/{petId}/photos ← Pet's photos
POST /pets/{petId}/photos ← Add photo
GET /pets/{petId}/vaccinations ← Pet's vaccinations
POST /pets/{petId}/vaccinations ← Record vaccination
GET /orders/{orderId}/items ← Order items
See the full REST API documentation for all endpoints.
Common Arguments for Singular (and Why They’re Wrong)
Let’s address common singular arguments.
Argument 1: “The Response Is Singular”
Claim: “When I GET /user/123, I get one user. Singular makes sense.”
Counter: The URL is about resource location, not response count. /users/123 means “item 123 in the users collection”—the response being singular doesn’t matter.
Argument 2: “It Reads Better in Code”
Claim: "getUser(id) is better than getUsers(id)."
Counter: Client code naming is independent from URL structure:
// URL: GET /users/123
function getUser(id) {
return api.get(`/users/${id}`);
}
Use singular names in code, plural in URLs.
Argument 3: “Singular Avoids Grammar Issues”
Claim: “‘Status’ or ‘information’ have no plurals.”
Counter: These are singleton resources, not collections. Use singular for singletons:
GET /status ← System status
GET /configuration ← App config
GET /users ← Users collection (plural)
Argument 4: “My ORM Uses Singular Table Names”
Claim: “My DB tables are singular (user), so my API should match.”
Counter: API design is not tied to your database schema. REST APIs represent resources, not tables. Collections are always plural at the API level.
Testing Resource Naming with Apidog
Apidog helps validate and test resource naming conventions.
Import Modern PetstoreAPI
- Import the Modern PetstoreAPI OpenAPI spec.
- Apidog auto-detects resource patterns.
- Review endpoint naming for consistency.
Create Naming Convention Tests
// Apidog test script
pm.test("Resource names are plural", function() {
const path = pm.request.url.getPath();
const segments = path.split('/').filter(s => s);
// Check first segment is plural
const resource = segments[0];
pm.expect(resource).to.match(/s$/); // Ends with 's'
});
Validate Consistency
Apidog can check:
- All collections use plural names
- Sub-resources follow the same pattern
- No mixing of singular/plural in the same API
Test with Real Requests
GET https://api.petstoreapi.com/v1/pets
GET https://api.petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24
GET https://api.petstoreapi.com/v1/orders
Apidog validates responses and ensures naming consistency across your API.
Edge Cases and Exceptions
Some resources don’t fit the plural pattern.
Singleton Resources
Use singular for resources that exist only once:
GET /status ← System status
GET /configuration ← App configuration
GET /health ← Health check
GET /metrics ← System metrics
Controller Resources
Actions, not collections:
POST /login ← Authentication action
POST /logout ← Session termination
POST /search ← Complex search
Uncountable Nouns
Use singular for uncountable nouns:
GET /information
GET /data
GET /equipment
These are rare in typical APIs.
Modern PetstoreAPI Approach
Modern PetstoreAPI handles cases as follows:
# Collections (plural)
GET /pets
GET /orders
GET /users
# Singletons (singular)
GET /health
GET /metrics
# Actions (singular verbs)
POST /login
POST /logout
Conclusion
REST API resource names should be plural. This matches collection semantics, HTTP methods, and industry standards. Modern PetstoreAPI demonstrates this pattern consistently.
Key takeaways:
- Use plural names for collections (
/pets,/orders,/users) - Access individual items within collections (
/pets/123) - Singleton resources can be singular (
/status,/health) - Prioritize consistency
- Test naming conventions with Apidog
The debate is settled. Use plural names for intuitive, maintainable APIs.
Next steps:
- Review your API endpoints for naming consistency
- Check Modern PetstoreAPI documentation for samples
- Use Apidog to validate your API design
- Update your OpenAPI spec with plural resource names
FAQ
Should I change my existing API from singular to plural?
If your API is in production, changing resource names is breaking. Instead:
- Add new v2 endpoints with plural names
- Maintain backward compatibility
- Document the naming convention clearly
Don’t break clients just for naming consistency.
What about resources that are already plural?
If the name is naturally plural (e.g., “analytics”, “series”), keep it as-is:
GET /analytics
GET /series
GET /species
How do I handle nested resources?
Keep both levels plural:
GET /users/{userId}/orders
GET /pets/{petId}/vaccinations
GET /orders/{orderId}/items
What if my team prefers singular?
Consistency is key. If your API is already standardized on singular, keep it. But for new APIs, use plural.
Does GraphQL use plural or singular?
GraphQL typically uses singular for single-item queries, plural for lists:
query {
user(id: "123") { ... } # Singular
users(limit: 10) { ... } # Plural
}
GraphQL queries are explicit about returning one vs many.
How does Modern PetstoreAPI handle this?
Modern PetstoreAPI uses plural names for all REST endpoints. See the REST API guide for examples.
Can I test naming conventions automatically?
Yes, Apidog can run automated tests to check resource naming patterns. Import your OpenAPI spec and create naming test cases.
What about non-English APIs?
The plural rule applies for all languages. Use plurals according to your API’s language grammar. The principle—collections are plural—remains.
Top comments (0)