Isaac.

api-development

REST API Design Best Practices

Build RESTful APIs that are intuitive, scalable, and maintainable.

By Emem IsaacJuly 18, 20243 min read
#rest#api#design#best-practices#http#conventions
Share:

A Simple Analogy

A well-designed REST API is like a well-organized library. Books (resources) are organized logically, labeled clearly, and there's a standard system to find and retrieve them. Clients know exactly how to locate what they need without guidance.


What Makes a Good REST API?

A good REST API is intuitive, consistent, scalable, and predictable. Clients can understand and use it without extensive documentation because it follows conventions.


Core REST Principles

| Principle | Meaning | |-----------|---------| | Resources | Everything is a resource (users, orders, products) | | HTTP Methods | Use GET, POST, PUT, DELETE appropriately | | Status Codes | Communicate success/failure clearly | | Stateless | Each request is independent | | Representations | Resources returned as JSON/XML |


Resource Design

Good:
GET    /api/users              # List users
POST   /api/users              # Create user
GET    /api/users/:id          # Get specific user
PUT    /api/users/:id          # Update user
DELETE /api/users/:id          # Delete user

Bad:
GET    /api/getUsers
POST   /api/createUser
GET    /api/getUserById
POST   /api/updateUser
POST   /api/deleteUser

HTTP Status Codes

// Success
200 OK              // Request succeeded
201 Created         // Resource created
204 No Content      // Success, no response body

// Client Errors
400 Bad Request     // Invalid input
401 Unauthorized    // Authentication required
403 Forbidden       // Authenticated but not allowed
404 Not Found       // Resource doesn't exist
409 Conflict        // Request conflicts (duplicate)

// Server Errors
500 Internal Error  // Server error
503 Service Unavailable  // Server temporarily down

Practical Example

[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
    [HttpGet("{id}")]
    public async Task<ActionResult<OrderDto>> GetOrder(int id)
    {
        var order = await _orderService.GetOrderAsync(id);
        if (order == null)
            return NotFound();  // 404
        return Ok(order);       // 200
    }
    
    [HttpPost]
    public async Task<ActionResult<OrderDto>> CreateOrder(CreateOrderDto dto)
    {
        var order = await _orderService.CreateAsync(dto);
        return CreatedAtAction(nameof(GetOrder), new { id = order.Id }, order);  // 201
    }
    
    [HttpPut("{id}")]
    public async Task<IActionResult> UpdateOrder(int id, UpdateOrderDto dto)
    {
        var success = await _orderService.UpdateAsync(id, dto);
        if (!success)
            return NotFound();  // 404
        return NoContent();     // 204
    }
}

Best Practices

  1. Use nouns, not verbs: /orders not /getOrders
  2. Consistent naming: Plurals, lowercase, hyphens: /users, /product-categories
  3. Pagination: GET /users?page=1&limit=10
  4. Filtering: GET /orders?status=pending&date=2025-02-20
  5. Versioning: GET /api/v1/users or header-based
  6. Documentation: Clear error messages and swagger
  7. Error responses: Consistent format
    {
      "error": "Invalid input",
      "code": 400,
      "details": "Email is required"
    }
    

Real-World Example

User Orders API

GET    /api/v1/users/:userId/orders
       Returns: [{ id, date, status, total }]

POST   /api/v1/users/:userId/orders
       Body: { items: [...], shippingAddress: {...} }
       Returns: 201 + { id, orderNumber, ... }

GET    /api/v1/orders/:orderId
       Returns: { id, items, status, total, dates }

PUT    /api/v1/orders/:orderId
       Body: { status: "shipped", trackingNumber: "..." }
       Returns: 204

Related Concepts to Explore

  • GraphQL (alternative to REST)
  • API versioning strategies
  • Rate limiting and throttling
  • HATEOAS (Hypermedia)
  • OpenAPI/Swagger documentation

Summary

Good REST API design follows HTTP conventions, uses intuitive resource naming, and clear status codes. This makes APIs discoverable, maintainable, and a pleasure to use.

Share:

Written by Emem Isaac

Expert Software Engineer with 15+ years of experience building scalable enterprise applications. Specialized in ASP.NET Core, Azure, Docker, and modern web development. Passionate about sharing knowledge and helping developers grow.

Ready to Build Something Amazing?

Let's discuss your project and explore how my expertise can help you achieve your goals. Free consultation available.

💼 Trusted by 50+ companies worldwide | ⚡ Average response time: 24 hours