DEV Community

Cover image for Why Shouldn't You Use Verbs in REST API URLs?
Wanda
Wanda

Posted on • Originally published at apidog.com

Why Shouldn't You Use Verbs in REST API URLs?

TL;DR

REST API URLs should use nouns (resources), not verbs (actions). HTTP methods (GET, POST, PUT, DELETE) are the verbs. Using actions like /getUser or /createOrder in URLs violates REST principles, creates inconsistency, and makes APIs harder to maintain. Modern PetstoreAPI uses resource-oriented URLs throughout.

Try Apidog today


Introduction

When designing an API endpoint to search for pets by status, you might consider: GET /findPetsByStatus?status=available. While descriptive, this approach is incorrect in REST.

REST APIs should use nouns in URLs, not verbs. The HTTP method represents the action. The correct endpoint: GET /pets?status=available. The URL targets the resource (pets), and the HTTP method specifies the action (get).

The old Swagger Petstore used endpoints like /pet/findByStatus and /pet/findByTags, which violate REST conventions. Modern PetstoreAPI corrects this with resource-oriented URLs.

💡 Tip: If you're building or testing REST APIs, Apidog can help you validate URL design, test endpoints, and enforce REST conventions. Import OpenAPI specs, check for verbs in URLs, and catch design issues early.

This guide covers why verbs don’t belong in REST URLs, how to design resource-oriented endpoints, and how Modern PetstoreAPI implements this correctly.


The Verb Problem in REST APIs

Action verbs in URLs indicate RPC (Remote Procedure Call) thinking, not REST.

RPC-Style URLs (Wrong)

POST /createUser
GET /getUser?id=123
PUT /updateUser
DELETE /deleteUser?id=123
GET /findUsersByRole?role=admin
POST /sendEmail
GET /calculateTotal
Enter fullscreen mode Exit fullscreen mode

These are function calls, not REST endpoints.

REST-Style URLs (Correct)

POST /users
GET /users/123
PUT /users/123
DELETE /users/123
GET /users?role=admin
POST /emails
GET /orders/123/total
Enter fullscreen mode Exit fullscreen mode

URLs represent resources; HTTP methods specify actions.

Why This Matters

Consistency: REST URLs follow predictable patterns based on resources:

  • GET /pets – List pets
  • POST /pets – Create pet
  • GET /pets/{id} – Get pet
  • PUT /pets/{id} – Update pet
  • DELETE /pets/{id} – Delete pet

Verb-based URLs are inconsistent and unpredictable.

Scalability: Verb-based URLs multiply as features grow:

  • /findPetsByStatus
  • /findPetsByTags
  • /findPetsByOwner
  • /findPetsByBreed
  • /searchPets
  • /queryPets

With resource-oriented URLs, a single endpoint handles filtering:

  • GET /pets?status=available
  • GET /pets?tags=friendly
  • GET /pets?owner=john
  • GET /pets?breed=labrador

Why HTTP Methods Are the Verbs

REST leverages HTTP’s built-in verbs so you don’t need to invent your own.

HTTP Methods Map to CRUD

POST   → Create
GET    → Read
PUT    → Update (replace)
PATCH  → Update (partial)
DELETE → Delete
Enter fullscreen mode Exit fullscreen mode
  • GET is safe and idempotent.
  • POST creates resources.
  • DELETE removes them.

Example: User Management

Wrong (verbs in URLs):

POST /createUser
GET /getUser?id=123
POST /updateUser
POST /deleteUser
Enter fullscreen mode Exit fullscreen mode

Correct (HTTP methods as verbs):

POST /users           # Create user
GET /users/123        # Get user
PUT /users/123        # Update user
DELETE /users/123     # Delete user
Enter fullscreen mode Exit fullscreen mode

The resource stays the same; only the method changes.

Benefits of Using HTTP Methods

  1. Caching: GET requests can be cached. Using POST /getUser prevents proper caching.
  2. Idempotency: PUT and DELETE are idempotent, supporting safe retries.
  3. Safety: GET does not modify state; it’s safe for crawlers/tools.
  4. Standards Compliance: HTTP clients, proxies, and caches understand standard methods, not custom verbs.

Real Examples from Swagger Petstore

Example 1: Finding Pets by Status

Swagger Petstore (Wrong):

GET /pet/findByStatus?status=available
Enter fullscreen mode Exit fullscreen mode

Problems:

  • findByStatus is a verb phrase
  • Inconsistent with /pet/{id}
  • Hard to extend (e.g., other search criteria)

Modern PetstoreAPI (Correct):

GET /pets?status=AVAILABLE
Enter fullscreen mode Exit fullscreen mode

Benefits:

  • Resource-oriented (/pets)
  • Uses query parameters for filtering
  • Consistent and easy to extend: GET /pets?status=AVAILABLE&species=dog

See the Modern PetstoreAPI REST documentation for detailed implementation.

Example 2: Finding Pets by Tags

Swagger Petstore (Wrong):

GET /pet/findByTags?tags=tag1,tag2
Enter fullscreen mode Exit fullscreen mode

Modern PetstoreAPI (Correct):

GET /pets?tags=friendly,trained
Enter fullscreen mode Exit fullscreen mode

Example 3: User Login

Swagger Petstore (Wrong):

GET /user/login?username=john&password=secret
Enter fullscreen mode Exit fullscreen mode

Problems:

  • login is a verb
  • Using GET for authentication (security risk)
  • Passwords in URL parameters

Modern PetstoreAPI (Correct):

POST /auth/login
Content-Type: application/json

{
  "username": "john",
  "password": "secret123"
}
Enter fullscreen mode Exit fullscreen mode

Benefits:

  • Resource-oriented (/auth)
  • Uses POST
  • Credentials in request body
  • Returns JWT token

How Modern PetstoreAPI Fixes This

Modern PetstoreAPI uses resource-oriented URLs for all endpoints.

Pet Management

GET /pets                    # List all pets
GET /pets?status=AVAILABLE   # Filter by status
GET /pets?species=dog        # Filter by species
GET /pets/{id}               # Get specific pet
POST /pets                   # Create new pet
PUT /pets/{id}               # Update pet
PATCH /pets/{id}             # Partial update
DELETE /pets/{id}            # Delete pet
Enter fullscreen mode Exit fullscreen mode

No verbs in URLs—just resources.

Order Management

GET /orders                  # List orders
GET /orders/{id}             # Get order
POST /orders                 # Create order
PUT /orders/{id}             # Update order
DELETE /orders/{id}          # Cancel order
GET /orders/{id}/items       # Get order items
Enter fullscreen mode Exit fullscreen mode

Complex Operations

For operations beyond standard CRUD, use sub-resources:

POST /orders/{id}/payment    # Process payment for order
POST /orders/{id}/shipment   # Create shipment for order
POST /pets/{id}/adoption     # Start adoption process
Enter fullscreen mode Exit fullscreen mode

These sub-resources still follow resource-oriented patterns.


When Verbs Seem Necessary

Some operations don’t fit CRUD exactly. Here’s how to keep URLs resource-oriented.

Search Operations

Wrong:

GET /searchPets?query=labrador
Enter fullscreen mode Exit fullscreen mode

Correct (Option 1):

GET /pets?search=labrador
Enter fullscreen mode Exit fullscreen mode

Correct (Option 2):

GET /pets/search?q=labrador
Enter fullscreen mode Exit fullscreen mode

Correct (Option 3):

QUERY /pets
Content-Type: application/json

{
  "query": "labrador",
  "filters": {
    "status": "AVAILABLE"
  }
}
Enter fullscreen mode Exit fullscreen mode

Modern PetstoreAPI supports all three depending on complexity.

Calculations

Wrong:

GET /calculateShipping?weight=10&destination=NY
Enter fullscreen mode Exit fullscreen mode

Correct:

GET /shipping-estimates?weight=10&destination=NY
Enter fullscreen mode Exit fullscreen mode

Use resources (shipping-estimates), not actions.

Batch Operations

Wrong:

POST /batchDeletePets
Enter fullscreen mode Exit fullscreen mode

Correct:

DELETE /pets?ids=1,2,3
Enter fullscreen mode Exit fullscreen mode

Or, use a batch resource:

POST /pets/batch-operations
Content-Type: application/json

{
  "operation": "delete",
  "ids": [1, 2, 3]
}
Enter fullscreen mode Exit fullscreen mode

Actions That Change State

Wrong:

POST /activateUser
POST /deactivateUser
Enter fullscreen mode Exit fullscreen mode

Correct:

PATCH /users/{id}
Content-Type: application/json

{
  "status": "ACTIVE"
}
Enter fullscreen mode Exit fullscreen mode

State changes should be modeled as resource updates.


Testing URL Design with Apidog

Apidog helps validate REST API design and identify verbs in URLs.

Import Modern PetstoreAPI

  1. Import the Modern PetstoreAPI OpenAPI spec
  2. Apidog generates test cases automatically
  3. Review endpoint structure and naming

Check for Verbs in URLs

Create a custom validation rule in Apidog:

// Check if URL contains common action verbs
const verbs = ['get', 'create', 'update', 'delete', 'find', 'search',
               'calculate', 'process', 'send', 'fetch'];
const url = request.url.toLowerCase();

for (const verb of verbs) {
  if (url.includes(`/${verb}`)) {
    throw new Error(`URL contains verb: ${verb}. Use resource-oriented URLs instead.`);
  }
}
Enter fullscreen mode Exit fullscreen mode

Test Endpoint Consistency

Apidog can verify endpoint patterns:

✓ GET /pets
✓ POST /pets
✓ GET /pets/{id}
✓ PUT /pets/{id}
✓ DELETE /pets/{id}
Enter fullscreen mode Exit fullscreen mode

All share the /pets resource.

Compare Against Modern PetstoreAPI

  1. Import your API and Modern PetstoreAPI into Apidog
  2. Compare endpoint structures side-by-side
  3. Identify inconsistencies or verb usage
  4. Refactor your API to match REST conventions

Migration Strategies

If your API uses verbs in URLs, use these migration steps.

Strategy 1: Versioning

Release a new version with correct URLs:

# Old API (v1)
GET /api/v1/findPetsByStatus?status=available

# New API (v2)
GET /api/v2/pets?status=available
Enter fullscreen mode Exit fullscreen mode

Maintain v1, but encourage migration to v2.

Strategy 2: Aliasing

Support old and new URLs temporarily:

# Old URL (deprecated)
GET /pet/findByStatus?status=available

# New URL (preferred)
GET /pets?status=available
Enter fullscreen mode Exit fullscreen mode

Return a deprecation warning:

{
  "data": [...],
  "warnings": [
    {
      "code": "DEPRECATED_ENDPOINT",
      "message": "This endpoint is deprecated. Use GET /pets?status=available instead.",
      "sunset": "2027-01-01"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Strategy 3: Redirects

Use HTTP 301 redirects for simple cases:

GET /pet/findByStatus?status=available
→ 301 Moved Permanently
Location: /pets?status=available
Enter fullscreen mode Exit fullscreen mode

Works for GET requests, not for POST, PUT, or DELETE.


Conclusion

REST API URLs should use nouns (resources); HTTP methods provide the verbs. This ensures consistency, scalability, and maintainability.

The old Swagger Petstore used endpoints like /pet/findByStatus. Modern PetstoreAPI corrects this with resource-oriented URLs, such as /pets?status=AVAILABLE.

Key takeaways:

  • Use nouns in URLs: /pets, /orders, /users
  • Let HTTP methods be the verbs: GET, POST, PUT, DELETE
  • Use query parameters for filtering: /pets?status=available
  • For complex operations, use sub-resources: /orders/{id}/payment
  • Test your API design with Apidog to catch verb usage early

Review the Modern PetstoreAPI documentation for more examples.


FAQ

Can I ever use verbs in REST URLs?

Rarely. If an operation doesn’t fit the resource model (e.g., /search or /login), a verb might be justified. In most cases, model it as a resource.

What about /login and /logout?

These are common exceptions. Many APIs use /auth/login and /auth/logout. Alternatively, use resources: POST /sessions (login) and DELETE /sessions/{id} (logout).

How do I handle complex queries?

Use query parameters for simple filters: /pets?status=available&species=dog. For complex queries, use the QUERY HTTP method or a search resource: POST /pets/search.

What if my operation doesn’t map to CRUD?

Model it as a sub-resource. Instead of POST /processPayment, use POST /orders/{id}/payment.

How do I test if my URLs are resource-oriented?

Use Apidog to import your OpenAPI spec and check for verbs in URLs. Compare against Modern PetstoreAPI as a reference.

Should I use /pets/search or /pets?search=query?

Both are valid. /pets?search=query is simpler for basic search. /pets/search or QUERY /pets is better for complex queries.

How do I migrate from verb-based URLs?

Use API versioning (e.g., /v2/pets), add deprecation warnings, and give clients time to migrate. See the Migration Strategies section above.

Does Modern PetstoreAPI use any verbs in URLs?

Modern PetstoreAPI avoids verbs in URLs. Operations like search, filter, and authentication are modeled as resources or use query parameters. Review the REST API documentation for examples.

Top comments (0)