Skip to main content
Back to Blog
1 August 202514 min read

API Design Best Practices: Lessons from Building Enterprise APIs

API DesignRESTArchitectureBest Practices

Principles for designing APIs that developers love. Consistency, versioning strategies, error handling, and documentation approaches.


API Design Best Practices: Lessons from Building Enterprise APIs

After designing and maintaining APIs consumed by hundreds of developers across multiple organizations, I've learned that good API design is fundamentally about consistency, predictability, and developer experience. The best APIs feel intuitive—developers can often guess the endpoint structure without reading documentation.

The Foundation: Resource-Oriented Design

REST APIs model resources, not actions. This distinction matters more than it seems.

Good Resource Design

# Resources (nouns, not verbs)
GET    /users              # List users
GET    /users/{id}         # Get specific user
POST   /users              # Create user
PUT    /users/{id}         # Replace user
PATCH  /users/{id}         # Partial update
DELETE /users/{id}         # Delete user

# Nested resources for relationships
GET    /users/{id}/orders  # User's orders
POST   /users/{id}/orders  # Create order for user

Avoid Action-Based URLs

# Bad: Verbs in URLs
POST /createUser
POST /users/delete/{id}
GET  /getUserOrders

# Good: Let HTTP methods convey the action
POST   /users
DELETE /users/{id}
GET    /users/{id}/orders

Consistency is King

Consistency reduces cognitive load. When developers learn one pattern, they should be able to apply it everywhere.

Naming Conventions

Pick conventions and apply them universally:

// Consistent: camelCase everywhere { "userId": "123", "firstName": "John", "lastName": "Smith", "emailAddress": "john@example.com", "createdAt": "2024-01-15T10:30:00Z" } // Inconsistent: Mixed conventions (avoid) { "user_id": "123", "FirstName": "John", "last-name": "Smith" }

My recommendation: Use camelCase for JSON fields (JavaScript convention), snake_case for query parameters (URL convention), and kebab-case for URL paths.

Consistent Response Envelopes

Wrap all responses in a consistent structure:

// Success response { "data": { "id": "123", "name": "John Smith" }, "meta": { "requestId": "req-abc-123", "timestamp": "2024-01-15T10:30:00Z" } } // Collection response { "data": [ { "id": "1", "name": "Item 1" }, { "id": "2", "name": "Item 2" } ], "meta": { "requestId": "req-abc-124", "timestamp": "2024-01-15T10:30:00Z" }, "pagination": { "page": 1, "pageSize": 20, "totalItems": 150, "totalPages": 8 } }

Versioning Strategies

API versioning is inevitable—the question is how to handle it gracefully.

URL Path Versioning

GET /v1/users
GET /v2/users

Pros: Explicit, easy to debug, simple to route, cache-friendly

Cons: Duplicates URLs, can lead to "version explosion"

Header Versioning

GET /users
Accept: application/vnd.company.v2+json

Pros: Clean URLs, encourages backward compatibility

Cons: Harder to debug (curl commands more complex), caching complications

Query Parameter Versioning

GET /users?version=2

Pros: Simple to implement, visible in logs

Cons: Optional parameter temptation, query string pollution

My Recommendation

Use URL versioning (\

Share this article