Skip to content

Restful Best Practices

DodaTech 2 min read

title: "RESTful Best Practices — Guidelines for Building REST APIs" description: "RESTful best practices cover consistent naming, proper HTTP method usage, stateless design, caching, error handling, and security patterns for production APIs." date: 2026-06-28 lastmod: 2026-06-28 weight: 26 tags: [apis, restful] }

RESTful best practices compile proven patterns for resource naming, HTTP method usage, status code selection, error handling, caching, and security in REST APIs.

What You'll Learn

  • Resource design conventions
  • HTTP method usage rules
  • API organization patterns

Why It Matters

Following best practices produces APIs that are predictable, consistent, and easy to use. Developers familiar with REST can immediately work with your API.

Best Practices Summary

# 1. Use plural nouns for resources
GET    /users        # Good
GET    /user         # Bad
POST   /users        # Good
POST   /createUser   # Bad

# 2. Use HTTP methods correctly
GET    /users        # List
GET    /users/1      # Retrieve
POST   /users        # Create
PUT    /users/1      # Replace
PATCH  /users/1      # Partial update
DELETE /users/1      # Delete

# 3. Consistent status codes
200  # Success
201  # Created
204  # No content (delete)
400  # Bad request
401  # Unauthorized
403  # Forbidden
404  # Not found
409  # Conflict
422  # Validation error
429  # Rate limited
500  # Internal error

# 4. Version your API
/api/v1/users
/api/v2/users

# 5. Use consistent error format
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid input",
    "details": [...]
  }
}

# 6. Paginate collections
GET /users?page=2&limit=20

# 7. Support filtering and sorting
GET /users?status=active&sort_by=name

# 8. Use HTTPS everywhere
# 9. Include rate limit headers
# 10. Document with OpenAPI
// Best practice: consistent route structure
const express = require('express');
const router = express.Router();

// Collection routes
router.get('/users', listUsers);
router.post('/users', createUser);

// Item routes
router.get('/users/:id', getUser);
router.put('/users/:id', updateUser);
router.patch('/users/:id', patchUser);
router.delete('/users/:id', deleteUser);

// Nested routes (max 2 levels)
router.get('/users/:id/orders', listUserOrders);
router.post('/users/:id/orders', createUserOrder);
router.get('/users/:id/orders/:orderId', getUserOrder);

// Action routes (non-CRUD)
router.post('/users/:id/activate', activateUser);
router.post('/users/:id/deactivate', deactivateUser);

Common Mistakes

1. Inconsistent Resource Naming

Mix of /users and /getUserList and /User.

2. Wrong HTTP Methods

Using POST for everything, GET for mutations.

3. No Consistency Across Endpoints

Different endpoints use different naming, formats, or conventions.

4. Over-Engineering

Complex HATEOAS for a simple CRUD API with one client.

5. Ignoring Security Basics

No HTTPS, no auth, no input validation, no rate limiting.

Practice Questions

  1. What is the correct HTTP method for creating a resource?
  2. What is the correct HTTP method for updating a resource?
  3. How deep should nested resources go?
  4. What status code indicates a validation error?
  5. How do you handle non-CRUD operations?

Answers:

  1. POST.
  2. PUT (replace) or PATCH (partial update).
  3. Max 2-3 levels deep.
  4. 422 Unprocessable Entity or 400 Bad Request.
  5. Post to action endpoints: POST /users/{id}/activate.

Challenge: Audit a REST API against these best practices. Create a scorecard and identify areas for improvement.

FAQ

Should I use PUT or PATCH for updates?

: PUT for full replacement, PATCH for partial updates.

What is the difference between 400 and 422?

: 400 is generic bad request; 422 is specifically for validation errors.

How do I handle bulk operations in REST?

: POST to a collection with an array, or use a custom bulk endpoint.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro