Section 1 of 7

RESTful Principles

🎯 What You'll Learn

  • What REST is and why it matters
  • REST constraints and principles
  • Resource-based URLs
  • HTTP methods for CRUD operations
  • Status codes for API responses
  • Best practices for RESTful APIs

What is REST?

REST (Representational State Transfer) is an architectural style for designing networked applications. It uses HTTP methods to perform CRUD operations on resources.

💡 Key Concept

REST treats everything as a resource (product, user, order) that can be accessed via a unique URL and manipulated using standard HTTP methods.

REST Constraints

1. Client-Server Architecture

Separation of concerns: client handles UI, server handles data and business logic.

2. Stateless

Each request contains all information needed. Server doesn't store client state between requests.

3. Cacheable

Responses must define themselves as cacheable or non-cacheable.

4. Uniform Interface

Consistent way to interact with resources using standard HTTP methods.

5. Layered System

Client can't tell if connected directly to server or through intermediaries (load balancers, proxies).

Resource-Based URLs

URLs should represent resources (nouns), not actions (verbs).

❌ Bad (Action-Based) ✅ Good (Resource-Based)
/getProducts /products
/createProduct /products (POST)
/updateProduct/123 /products/123 (PUT)
/deleteProduct/123 /products/123 (DELETE)

URL Naming Conventions

  • Use nouns: /products, not /getProducts
  • Use plurals: /products, not /product
  • Use lowercase: /products, not /Products
  • Use hyphens: /order-items, not /orderItems
  • No trailing slashes: /products, not /products/

HTTP Methods for CRUD

Operation HTTP Method URL Description
Create POST /products Create a new product
Read (all) GET /products Get all products
Read (one) GET /products/123 Get product with ID 123
Update (full) PUT /products/123 Replace product 123
Update (partial) PATCH /products/123 Update parts of product 123
Delete DELETE /products/123 Delete product 123

Status Codes

Success Codes (2xx)

Code Name When to Use
200 OK Successful GET, PUT, PATCH
201 Created Successful POST (resource created)
204 No Content Successful DELETE, PUT (no response body)

Client Error Codes (4xx)

Code Name When to Use
400 Bad Request Invalid request data
401 Unauthorized Not authenticated
403 Forbidden Not authorized
404 Not Found Resource doesn't exist
409 Conflict Resource conflict (duplicate)

Complete RESTful API Example

InvenTrack Products API HTTP
// Get all products
GET /api/products
→ 200 OK
[
  { "id": 1, "name": "Laptop", "price": 999.99 },
  { "id": 2, "name": "Mouse", "price": 29.99 }
]

// Get single product
GET /api/products/1
→ 200 OK
{ "id": 1, "name": "Laptop", "price": 999.99 }

// Create product
POST /api/products
{ "name": "Keyboard", "price": 79.99 }
→ 201 Created
Location: /api/products/3
{ "id": 3, "name": "Keyboard", "price": 79.99 }

// Update product (full)
PUT /api/products/3
{ "name": "Mechanical Keyboard", "price": 129.99 }
→ 200 OK or 204 No Content

// Update product (partial)
PATCH /api/products/3
{ "price": 99.99 }
→ 200 OK or 204 No Content

// Delete product
DELETE /api/products/3
→ 204 No Content

Nested Resources

For related resources, use nested URLs (but limit to 2 levels).

Nested Resources HTTP
// Get all orders for a customer
GET /api/customers/123/orders

// Get specific order for a customer
GET /api/customers/123/orders/456

// Create order for a customer
POST /api/customers/123/orders

// ❌ Too deep (avoid)
GET /api/customers/123/orders/456/items/789
⚠️ Avoid Deep Nesting

Limit nesting to 2 levels. For deeper relationships, use query parameters or separate endpoints.

Filtering, Sorting, and Pagination

Filtering

Query Parameters for Filtering HTTP
GET /api/products?category=electronics
GET /api/products?minPrice=100&maxPrice=500
GET /api/products?inStock=true

Sorting

Query Parameters for Sorting HTTP
GET /api/products?sortBy=price
GET /api/products?sortBy=price&sortOrder=desc
GET /api/products?sortBy=name,price

Pagination

Query Parameters for Pagination HTTP
GET /api/products?page=1&pageSize=20
GET /api/products?skip=20&take=20

// Response with pagination metadata
{
  "data": [...],
  "page": 1,
  "pageSize": 20,
  "totalCount": 100,
  "totalPages": 5
}

Best Practices

  • Use nouns for resources: /products, not /getProducts
  • Use HTTP methods correctly: GET for read, POST for create, etc.
  • Return appropriate status codes: 200, 201, 204, 400, 404, etc.
  • Use plural nouns: /products, not /product
  • Version your API: /api/v1/products
  • Use HTTPS: Always in production
  • Consistent naming: Use lowercase and hyphens
  • Limit nesting: Maximum 2 levels
  • Support filtering/sorting/pagination: For collections
  • Include Location header: For 201 Created responses
  • Use JSON: Default format for APIs
  • Document your API: Use Swagger/OpenAPI

RESTful API Checklist

  • ✅ Resource-based URLs (nouns, not verbs)
  • ✅ Proper HTTP methods (GET, POST, PUT, PATCH, DELETE)
  • ✅ Correct status codes (2xx, 4xx, 5xx)
  • ✅ Stateless (no server-side sessions)
  • ✅ JSON format
  • ✅ Pagination for large collections
  • ✅ Filtering and sorting support
  • ✅ Versioning strategy
  • ✅ HTTPS in production
  • ✅ API documentation

Key Takeaways

  • REST: Architectural style using HTTP for CRUD operations
  • Resources: Everything is a resource with a unique URL
  • HTTP methods: GET (read), POST (create), PUT (update), DELETE (delete)
  • Status codes: 200 OK, 201 Created, 204 No Content, 400 Bad Request, 404 Not Found
  • Nouns, not verbs: /products, not /getProducts
  • Stateless: Each request is independent
  • Consistent naming: Lowercase, plurals, hyphens
  • Pagination: For large collections
  • Versioning: Plan for API evolution
🎯 Next Steps

You now understand RESTful principles! In the next section, we'll explore API Controllers—how to implement RESTful APIs in ASP.NET Core using controllers and attributes.