D2 Enterprises
API Design • 11 min read

RESTful API Design: Principles for Modern Applications

PA

Parijat Anand

CTO at D2 Enterprises

Abstract visualization of API endpoints connecting different services with data flowing between them

APIs are the backbone of modern applications, connecting services, enabling integrations, and powering user experiences. A well-designed RESTful API is intuitive, scalable, and maintainable. A poorly designed one becomes a source of frustration and technical debt. Let's explore the principles that separate great APIs from mediocre ones.

What Makes a Great API?

Before diving into specific patterns, let's establish what we're aiming for:

1. Resource-Based URL Design

REST is built around resources (nouns), not actions (verbs). URLs should represent resources, and HTTP methods should represent actions on those resources.

Good URL Design

GET /api/users # Get all users
GET /api/users/123 # Get specific user
POST /api/users # Create new user
PUT /api/users/123 # Update user
PATCH /api/users/123 # Partial update
DELETE /api/users/123 # Delete user

GET /api/users/123/orders # Get user's orders
GET /api/orders/456 # Get specific order

Poor URL Design (Avoid)

GET /api/getUsers # Don't use verbs
POST /api/user/create # Redundant
GET /api/deleteUser?id=123 # Wrong HTTP method
GET /api/users-orders # Unclear relationship

URL Design Best Practices

2. HTTP Methods and Status Codes

Use HTTP methods correctly to indicate the type of operation, and return appropriate status codes to communicate results.

HTTP Methods

Common Status Codes

3. Request and Response Design

Consistent request and response formats make your API predictable and easy to use.

Request Body Example

POST /api/users
Content-Type: application/json

{
"firstName": "John",
"lastName": "Doe",
"email": "[email protected]",
"role": "developer"
}

Success Response Example

HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/users/123

{
"id": "123",
"firstName": "John",
"lastName": "Doe",
"email": "[email protected]",
"role": "developer",
"createdAt": "2024-12-05T10:30:00Z",
"updatedAt": "2024-12-05T10:30:00Z"
}

Error Response Example

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json

{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{
"field": "email",
"message": "Email is already registered"
},
{
"field": "firstName",
"message": "First name is required"
}
]
}
}

Response Design Best Practices

4. Filtering, Sorting, and Pagination

Large datasets require efficient querying mechanisms. Implement these through query parameters.

Filtering

GET /api/users?role=developer&status=active
GET /api/products?category=electronics&price[gte]=100&price[lte]=500
GET /api/orders?createdAfter=2024-01-01&status=pending

Sorting

GET /api/users?sort=lastName # Ascending
GET /api/users?sort=-createdAt # Descending (- prefix)
GET /api/users?sort=lastName,-createdAt # Multiple fields

Pagination

Offset-based pagination:

GET /api/users?page=2&limit=20
GET /api/users?offset=40&limit=20

Cursor-based pagination (better for large datasets):

GET /api/users?cursor=eyJpZCI6MTIzfQ&limit=20

Response:
{
"data": [...],
"pagination": {
"nextCursor": "eyJpZCI6MTQzfQ",
"hasMore": true
}
}

Field Selection

GET /api/users?fields=id,firstName,lastName,email
GET /api/users?exclude=password,internalNotes

5. Versioning Strategies

APIs evolve, but breaking changes shouldn't break existing clients. Implement versioning from day one.

URL Versioning (Most Common)

GET /api/v1/users
GET /api/v2/users

Pros: Simple, visible, easy to route
Cons: URL changes, can lead to duplication

Header Versioning

GET /api/users
Accept: application/vnd.myapi.v2+json

Pros: Clean URLs, follows REST principles
Cons: Less visible, harder to test in browser

Versioning Best Practices

6. Authentication and Authorization

Secure your API with proper authentication and fine-grained authorization.

Authentication Methods

JWT Example

POST /api/auth/login
{
"email": "[email protected]",
"password": "securePassword123"
}

Response:
{
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "eyJhbGciOiJIUzI1NiIs...",
"expiresIn": 3600
}

Subsequent requests:
GET /api/users/me
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

Authorization Best Practices

7. Rate Limiting and Throttling

Protect your API from abuse and ensure fair usage across clients.

Rate Limit Headers

HTTP/1.1 200 OK
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 987
X-RateLimit-Reset: 1638720000

When exceeded:
HTTP/1.1 429 Too Many Requests
Retry-After: 3600
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Try again in 1 hour."
}
}

Rate Limiting Strategies

8. Caching Strategies

Leverage HTTP caching to improve performance and reduce server load.

Cache Headers

# Public, cacheable for 1 hour
Cache-Control: public, max-age=3600

# Private, cacheable for 5 minutes
Cache-Control: private, max-age=300

# Never cache
Cache-Control: no-store

# Validate before using cached version
Cache-Control: no-cache
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

ETags for Conditional Requests

GET /api/users/123
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

If unchanged:
HTTP/1.1 304 Not Modified

If changed:
HTTP/1.1 200 OK
ETag: "8f7e5b2c9d1a3e4f6b8c0d2e4f6a8b0c"
{...updated data...}

9. Documentation and Developer Experience

Great documentation is as important as great code. Make it easy for developers to understand and use your API.

Documentation Essentials

OpenAPI/Swagger

Use OpenAPI specification to generate interactive documentation automatically:

10. Testing and Monitoring

Ensure API reliability through comprehensive testing and monitoring.

Testing Layers

Monitoring Metrics

Common API Design Mistakes

Conclusion

Designing a great RESTful API requires attention to detail, consistency, and empathy for developers who will use it. Follow these principles to create APIs that are intuitive, scalable, and maintainable.

Remember that API design is about trade-offs. There's rarely one "correct" answer—choose patterns that fit your specific use case, team, and constraints. The most important thing is consistency and clear documentation.

At D2 Enterprises, we've designed and built APIs serving millions of requests daily. Whether you're building a new API or modernizing an existing one, these principles provide a solid foundation for success.

PA

About Parijat Anand

Parijat is the Chief Technology Officer at D2 Enterprises. Our backend specialists have designed and implemented RESTful APIs for diverse industries, from fintech to healthcare, combining technical expertise with a focus on developer experience.

View full profile →

Related Articles