Detailed Explanation of Each Point for REST API Development

1. What is a REST API?

REST (Representational State Transfer) is an architectural style for networked applications using stateless communication.

Key Aspects:

  • Works over HTTP/HTTPS.
  • Uses resources (users, products) represented by URLs.
  • Stateless.

Example:

https://api.example.com/v1/users/123

2. Key Features of REST API

Feature Explanation
Stateless Each request contains all data.
Client-Server Separation Frontend and backend are independent.
Uniform Interface Consistent format.
Cacheable Responses can be cached.
Layered System Supports proxies, load balancers.

3. HTTP Methods in REST API

HTTP methods are verbs for actions on resources.

Common verbs: GET, POST, PUT, PATCH, DELETE

Method CRUD Purpose
GET Read Retrieve Data
POST Create Add New Data
PUT Update Full Update
PATCH Update Partial Update
DELETE Delete Remove Data

3.1 GET - Retrieve Data

Purpose

Fetch data (read-only).

Characteristics

  • Idempotent.
  • Safe.

Example

GET /api/users/123

Response:

{
    "id": 123,
    "name": "John Doe",
    "email": "[email protected]"
}

Best Practices

  • ✅ Clear URLs.
  • ✅ Avoid sensitive data in URLs.

3.2 POST - Create New Resource

Purpose

Create a new resource.

Example

POST /api/products

Request Body:

{
    "name": "Wireless Mouse",
    "price": 25.99,
    "stock": 100
}

Key Considerations

  • ✅ Validate data.
  • ✅ Document required fields.

3.3 PUT - Update Resource

Purpose

Replace a resource.

Example

PUT /api/users/123

Request Body:

{
    "name": "John Updated",
    "email": "[email protected]"
}

Characteristics

  • Idempotent.

Best Practices

  • ✅ Send all fields.
  • ✅ Use for full updates.

3.4 PATCH - Partial Update

Purpose

Modify specific fields.

Example

PATCH /api/products/45

Request Body:

{
    "stock": 150
}

Key Considerations

  • ✅ Ensure data consistency.
  • ✅ Document allowed fields.

3.5 DELETE - Remove Resource

Purpose

Delete a resource.

Example

DELETE /api/orders/78

Characteristics

  • Idempotent.

Best Practices

  • ✅ Manage related data.
  • ✅ Consider soft delete.

4. Less Common HTTP Methods

4.1 HEAD - Retrieve Headers

Purpose

Get headers only.

Example

HEAD /api/products/45

Use Cases

  • Check if resource exists.
  • Get content length.

4.2 OPTIONS - Describe Operations

Purpose

Ask allowed HTTP methods.

Example

OPTIONS /api/products

Response:

Allow: GET, POST, PUT, DELETE

Use Case

  • CORS pre-flight requests.

5. Best Practices for API Design

1️⃣ Use Appropriate HTTP Method

Action Method
Fetch items GET
Create item POST
Full Update PUT
Partial Update PATCH
Delete item DELETE

2️⃣ Follow REST Principles

  • Nouns for resources.
  • Verbs in HTTP methods.

Example:

GET /users ✔️
POST /users ✔️
DELETE /users/123 ✔️

3️⃣ Return Proper Status Codes

Code Meaning
200 Success
201 Created
400 Bad Request
404 Not Found
500 Server Error

4️⃣ Secure Your API

  • ✅ Use HTTPS.
  • ✅ Validate inputs.
  • ✅ Use authentication.
  • ✅ Implement rate limiting.

5️⃣ Document Everything

Use tools like Swagger or Postman.

Example:

paths:
  /users:
    get:
      summary: Get all users
      responses:
        200:
          description: List of users

6. Quick Recap

Method Action Example
GET Read GET /users/123
POST Create POST /products
PUT Update PUT /users/123
PATCH Update PATCH /products/45
DELETE Remove DELETE /orders/78
HEAD Headers HEAD /products/45
OPTIONS Allowed OPTIONS /products

4. Steps to Develop a REST API

a) Define the Purpose

  • What data?
  • Who will use it?

b) Choose a Tech Stack

Language Framework
PHP Laravel, Slim
Node.js Express.js
Python Flask, FastAPI
Java Spring Boot

c) Setup Environment

  • Install runtime.
  • Setup database.

5. Design RESTful Endpoints

Rule: Nouns for resources, verbs in HTTP methods.

Action HTTP Endpoint Description
List Users GET /users Retrieve all.
Get User GET /users/{id} Retrieve specific.
Create User POST /users Add new.
Update User PUT /users/{id} Update data.
Delete User DELETE /users/{id} Remove.

6. Implement CRUD

PHP Example:

switch ($_SERVER['REQUEST_METHOD']) {
    case 'GET':
        if (isset($_GET['id'])) {
            getUser($_GET['id']);
        } else {
            getAllUsers();
        }
        break;
    case 'POST':
        createUser($_POST);
        break;
    case 'PUT':
        parse_str(file_get_contents("php://input"), $_PUT);
        updateUser($_GET['id'], $_PUT);
        break;
    case 'DELETE':
        deleteUser($_GET['id']);
        break;
}

Complete API Example

Below is a complete working example of a RESTful API with all CRUD operations and proper error handling:

1. Database Structure

CREATE TABLE items (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

2. Complete API Implementation (api.php)

setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
    header("Content-Type: application/json");
    http_response_code(500);
    echo json_encode(['message' => 'Database Connection Failed', 'error' => $e->getMessage()]);
    die();
}

// API Logic
header("Content-Type: application/json");
$method = $_SERVER['REQUEST_METHOD'];
$path = $_SERVER['PATH_INFO'] ?? '';

switch ($method) {
    case 'GET':
        handleGetRequest($conn, $path);
        break;
    case 'POST':
        handlePostRequest($conn);
        break;
    case 'PUT':
        handlePutRequest($conn, $path);
        break;
    case 'DELETE':
        handleDeleteRequest($conn, $path);
        break;
    default:
        http_response_code(405);
        echo json_encode(['message' => 'Method Not Allowed']);
        break;
}

function handleGetRequest($conn, $path) {
    if (empty($path) || $path === '/') {
        getAllItems($conn);
    } else {
        $id = intval(substr($path, 1));
        if ($id > 0) {
            getItemById($conn, $id);
        } else {
            http_response_code(400);
            echo json_encode(['message' => 'Invalid ID']);
        }
    }
}

function getAllItems($conn) {
    try {
        $stmt = $conn->query("SELECT * FROM items");
        echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC));
    } catch (PDOException $e) {
        http_response_code(500);
        echo json_encode(['message' => 'Error fetching items']);
    }
}

function getItemById($conn, $id) {
    try {
        $stmt = $conn->prepare("SELECT * FROM items WHERE id = ?");
        $stmt->execute([$id]);
        $item = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($item) {
            echo json_encode($item);
        } else {
            http_response_code(404);
            echo json_encode(['message' => 'Item not found']);
        }
    } catch (PDOException $e) {
        http_response_code(500);
        echo json_encode(['message' => 'Error fetching item']);
    }
}

function handlePostRequest($conn) {
    $input = json_decode(file_get_contents('php://input'), true);

    if (!validateInput($input)) {
        http_response_code(400);
        echo json_encode(['message' => 'Invalid input']);
        return;
    }

    try {
        $stmt = $conn->prepare("INSERT INTO items (name, email) VALUES (?, ?)");
        $stmt->execute([$input['name'], $input['email']]);
        
        http_response_code(201);
        echo json_encode([
            'message' => 'Item created',
            'id' => $conn->lastInsertId()
        ]);
    } catch (PDOException $e) {
        http_response_code(500);
        echo json_encode(['message' => 'Error creating item']);
    }
}

function handlePutRequest($conn, $path) {
    $id = intval(substr($path, 1));
    if ($id <= 0) {
        http_response_code(400);
        echo json_encode(['message' => 'Invalid ID']);
        return;
    }

    $input = json_decode(file_get_contents('php://input'), true);
    if (!validateInput($input)) {
        http_response_code(400);
        echo json_encode(['message' => 'Invalid input']);
        return;
    }

    try {
        $stmt = $conn->prepare("UPDATE items SET name = ?, email = ? WHERE id = ?");
        $stmt->execute([$input['name'], $input['email'], $id]);
        
        if ($stmt->rowCount() > 0) {
            echo json_encode(['message' => 'Item updated']);
        } else {
            http_response_code(404);
            echo json_encode(['message' => 'Item not found']);
        }
    } catch (PDOException $e) {
        http_response_code(500);
        echo json_encode(['message' => 'Error updating item']);
    }
}

function handleDeleteRequest($conn, $path) {
    $id = intval(substr($path, 1));
    if ($id <= 0) {
        http_response_code(400);
        echo json_encode(['message' => 'Invalid ID']);
        return;
    }

    try {
        $stmt = $conn->prepare("DELETE FROM items WHERE id = ?");
        $stmt->execute([$id]);
        
        if ($stmt->rowCount() > 0) {
            echo json_encode(['message' => 'Item deleted']);
        } else {
            http_response_code(404);
            echo json_encode(['message' => 'Item not found']);
        }
    } catch (PDOException $e) {
        http_response_code(500);
        echo json_encode(['message' => 'Error deleting item']);
    }
}

function validateInput($input) {
    return isset($input['name']) 
           && isset($input['email']) 
           && !empty($input['name']) 
           && !empty($input['email']) 
           && filter_var($input['email'], FILTER_VALIDATE_EMAIL);
}
?>

3. How to Use

Here are examples of how to interact with the API using cURL:

Get All Items

curl -X GET http://your-domain.com/api.php

Get Single Item

curl -X GET http://your-domain.com/api.php/1

Create New Item

curl -X POST http://your-domain.com/api.php \
     -H "Content-Type: application/json" \
     -d '{
         "name": "John Doe",
         "email": "[email protected]"
     }'

Update Item

curl -X PUT http://your-domain.com/api.php/1 \
     -H "Content-Type: application/json" \
     -d '{
         "name": "John Updated",
         "email": "[email protected]"
     }'

Delete Item

curl -X DELETE http://your-domain.com/api.php/1

4. Key Features

  • ✅ Full CRUD operations
  • ✅ PDO for database operations
  • ✅ Input validation
  • ✅ Proper error handling
  • ✅ HTTP status codes
  • ✅ JSON responses
  • ✅ Prepared statements for security
Note: Remember to:
  • Update database credentials
  • Create the database table
  • Add proper security measures (authentication, rate limiting)
  • Add proper logging
  • Implement CORS if needed

Complete PHP REST API Example

Here's a comprehensive example of a REST API implementation with database integration:

Features

  • PDO Database Connection
  • CRUD Operations
  • Error Handling
  • Input Validation
  • RESTful Endpoints

API Endpoints

Method Endpoint Description
GET /api.php Get all items
GET /api.php/{id} Get specific item
POST /api.php Create new item
PUT /api.php/{id} Update item
DELETE /api.php/{id} Delete item

Complete Code (api.php)

setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
    header("Content-Type: application/json");
    http_response_code(500);
    echo json_encode(['message' => 'Database Connection Failed']);
    die();
}

// API Logic Starts Here
header("Content-Type: application/json");
$method = $_SERVER['REQUEST_METHOD'];
$path = $_SERVER['PATH_INFO'] ?? '';

switch ($method) {
    case 'GET':
        handleGetRequest($conn, $path);
        break;
    case 'POST':
        handlePostRequest($conn);
        break;
    case 'PUT':
        handlePutRequest($conn, $path);
        break;
    case 'DELETE':
        handleDeleteRequest($conn, $path);
        break;
    default:
        http_response_code(405);
        echo json_encode(['message' => 'Method Not Allowed']);
        break;
}

Testing the API

Use cURL or Postman to test the endpoints:

# Get all items
curl -X GET http://your-domain.com/api.php

# Create new item
curl -X POST http://your-domain.com/api.php \
     -H "Content-Type: application/json" \
     -d '{"name":"John Doe","email":"[email protected]"}'

# Update item
curl -X PUT http://your-domain.com/api.php/1 \
     -H "Content-Type: application/json" \
     -d '{"name":"Jane Doe","email":"[email protected]"}'

# Delete item
curl -X DELETE http://your-domain.com/api.php/1

Key Features Explained

  1. Database Connection: Uses PDO for secure database operations
  2. Error Handling: Proper HTTP status codes and error messages
  3. Input Validation: Validates email and required fields
  4. Prepared Statements: Prevents SQL injection
  5. RESTful Design: Follows REST principles for endpoints
Note: Remember to:
  • Update database credentials
  • Create necessary database tables
  • Set proper permissions
  • Implement authentication if needed

7. Use Response Codes

Code Meaning
200 Success
201 Created
400 Bad Request
401 Unauthorized
404 Not Found
500 Server Error

Example:

{
    "status": 404,
    "message": "User not found"
}

8. Authentication

🔐 What is API Authentication?

Verifying the identity of a client accessing an API.

🚀 Key Methods

1️⃣ API Keys

🔧 How It Works

Unique token in each request.

✅ Example

GET /api/v1/users
Headers:
    Authorization: ApiKey xyz1234securetoken

📌 Suitable For

  • Internal services.
  • Low-security APIs.

⚠️ Limitations

  • No identity context.
  • Vulnerable to leaks.

2️⃣ JWT (JSON Web Token)

🔧 How It Works

Server generates signed token with claims.

✅ Example

GET /api/v1/orders
Headers:
    Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI...

📌 Suitable For

  • Microservices.
  • Stateless APIs.

🌟 Benefits

  • Self-contained.
  • Works across environments.

3️⃣ OAuth 2.0

🔧 How It Works

Delegated authorization for third-party access.

✅ Example Flow

App redirects to auth URL:

https://auth.example.com/oauth/authorize

App calls API with:

GET /api/v1/photos
Headers:
    Authorization: Bearer access_token_abc123

📌 Suitable For

  • Social logins.
  • Third-party apps.

🌟 Benefits

  • Fine-grained scopes.
  • Standardized.

🔎 Comparison

Method Security Stateless? Identity Use Case
API Keys Basic Internal APIs
JWT Strong Microservices
OAuth 2.0 Strong Third-party apps

✅ Choose Method

Scenario Method
Quick internal APIs API Key
Stateless API JWT
Third-party access OAuth 2.0

🔐 Best Practices

1️⃣ Enforce HTTPS

Encrypt traffic.

2️⃣ Secure Storage

Secure API Keys.

3️⃣ Rotate Secrets

Rotate keys/tokens.

4️⃣ Least Privilege

Grant minimal permissions.

5️⃣ Validate Inputs

Protect against injection.

6️⃣ Monitor Access

Log authentication events.

⚠️ Common Mistakes

Mistake Why It’s Risky
Exposing API Keys Unauthorized access.
Same key forever Risk of abuse.
Using HTTP Exposes credentials.
Skipping validation Injection attacks.
Excessive permissions Violates least privilege.

📣 Conclusion

9. Input Validation

Validate data to prevent SQL Injection.

PHP Example:

if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    http_response_code(400);
    echo json_encode(["error" => "Invalid email"]);
    exit;
}

10. Error Handling

Log errors and return clean messages.

Example:

{
    "error": "User not found",
    "code": 404
}

PHP Log:

error_log("User not found: ID " . $user_id);

11. Pagination

Paginate large datasets.

Example Query:

GET /users?page=2&limit=10

Example Response:

{
    "page": 2,
    "total_pages": 5,
    "data": [/* User list */]
}

12. Security

Security is a critical aspect of API development. Here are essential security best practices to protect your API from common vulnerabilities.

12.1 Input Validation

Always validate all incoming data to prevent injection attacks.

// Example: Validating 'id' parameter
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);

if ($id === false) {
    http_response_code(400);
    echo json_encode(["error" => "Invalid ID"]);
    exit;
}

12.2 Output Encoding

Encode all API responses to prevent cross-site scripting (XSS).

$name = htmlspecialchars($user['name'], ENT_QUOTES, 'UTF-8');
echo json_encode(['name' => $name]);

12.3 Authentication

Use strong authentication mechanisms:

  • OAuth 2.0
  • JWT (JSON Web Tokens)
  • API Keys
// JWT Authentication Example
$jwt = $_SERVER['HTTP_AUTHORIZATION'] ?? null;

if (!$jwt || !validateJWT($jwt)) {
    http_response_code(401);
    echo json_encode(['error' => 'Unauthorized']);
    exit;
}

12.4 Rate Limiting

Protect from abuse and DoS attacks:

$ip = $_SERVER['REMOTE_ADDR'];
$rateLimitKey = "rate_limit:$ip";

// Using Redis for tracking
$requests = $redis->incr($rateLimitKey);
$redis->expire($rateLimitKey, 60);  // 60 seconds window

if ($requests > 100) {
    http_response_code(429);
    echo json_encode(['error' => 'Too many requests']);
    exit;
}

12.5 HTTPS Enforcement

Always use HTTPS to encrypt data in transit:

if (empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === 'off') {
    header("Location: https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
    exit;
}

12.6 Secure Error Handling

Avoid exposing sensitive information in errors:

try {
    // Risky operation
} catch (Exception $e) {
    // Log detailed error internally
    error_log($e->getMessage());
    
    // Return generic error to client
    http_response_code(500);
    echo json_encode(['error' => 'An unexpected error occurred']);
}

12.7 Security Checklist

  • ✅ Validate all inputs
  • ✅ Use HTTPS everywhere
  • ✅ Implement proper authentication
  • ✅ Add rate limiting
  • ✅ Secure error handling
  • ✅ Regular security audits
  • ✅ Keep dependencies updated
  • ✅ Implement logging and monitoring

13. Documentation

Use Swagger or Postman.

Example:

{
    "openapi": "3.0.0",
    "paths": {
        "/users": {
            "get": {
                "summary": "Get all users",
                "responses": {
                    "200": {"description": "OK"}
                }
            }
        }
    }
}

14. Testing

  • Manual: Postman, cURL.
  • Automated: PHPUnit, Jest, PyTest.

PHPUnit Example:

public function testGetUsers() {
    $response = $this->get('/api/v1/users');
    $this->assertEquals(200, $response->status());
}

15. Versioning

Version APIs.

Example:

https://api.example.com/v1/users

16. Deployment

  • Cloud (AWS, DigitalOcean).
  • Reverse proxy (Nginx, Apache).

Monitor with:

  • New Relic
  • ELK Stack

17. Frameworks

Language Framework
PHP Laravel
Python Django
Node.js Express
Java Spring Boot

Final Checklist

  • ✅ RESTful Naming.
  • ✅ Validate Inputs.
  • ✅ Status Codes.
  • ✅ Document Endpoints.
  • ✅ Secure Data.
  • ✅ Monitor Performance.
  • ✅ Pagination.

HTTP Headers: A Deep Dive

Introduction

HTTP headers ensure efficient communication, strong security, and better user experience in web development.

What are HTTP Headers?

Metadata

Key-value pairs between client and server, providing context.

How to Inspect

1️⃣ Dev Tools

Right-click > Inspect > Network Tab

2️⃣ Curl

curl -I https://example.com

Key Headers

1️⃣ Content-Type

Purpose

Defines data format.

Example

Content-Type: application/json

2️⃣ Accept

Purpose

Client's preferred formats.

Example

Accept: application/json, text/html

3️⃣ Cache-Control

Purpose

Controls caching.

Example

Cache-Control: max-age=3600

5️⃣ Authorization

Purpose

Carries credentials.

Example

Authorization: Bearer your-jwt-token-here

Security Headers

1️⃣ HttpOnly

Purpose

Protects cookies from XSS.

Example

Set-Cookie: authToken=secureToken123; HttpOnly

2️⃣ Secure

Purpose

HTTPS-only cookies.

Example

Set-Cookie: session=abc123; Secure

3️⃣ CORS Headers

Purpose

Controls cross-origin access.

Example

Access-Control-Allow-Origin: https://trusted-site.com
Access-Control-Allow-Methods: GET, POST, PUT

4️⃣ X-Frame-Options

Purpose

Clickjacking protection.

Example

X-Frame-Options: DENY

Best Practices

Best Practice Why
Set Content-Type Correct parsing
Use CORS Safeguards API
HttpOnly + Secure Enhances security
X-Frame-Options Clickjacking protection
Cache wisely Improves speed
Secure Authorization Protects API

Quick Reference

Header Type Example Purpose
Content-Type Req/Resp application/json Data format
Accept Request application/json Response format
Cache-Control Response max-age=3600 Caching rules
Set-Cookie Response session=xyz123 Client data
Authorization Request Bearer token123 Auth
Access-Control-Allow-Origin Response https://your-frontend.com CORS
X-Frame-Options Response DENY Clickjacking

Conclusion

REST API Caching Strategies

🔥 Why Caching Matters

Caching allows the temporary storage of responses, reducing:

  • Server Load
  • Latency
  • Bandwidth Usage

⚙️ Types of Caching Strategies

1️⃣ Client-Side Caching

🔧 What is it?

Client caches API responses locally.

📂 Key Types

  • Browser Caching
  • Mobile App Caching

✅ Example: Browser Caching

GET /products
Cache-Control: max-age=3600

Caches response for 1 hour.

🚨 When to Use

  • Static data.
  • Offline functionality.

2️⃣ Server-Side Caching

🔧 What is it?

API infrastructure caches responses.

📂 Key Types

  • Reverse Proxy Cache
  • CDN Cache
  • API Gateway Cache

✅ Example: CDN Cache

GET https://cdn.example.com/api/products

CDN responds directly.

🚨 When to Use

  • Public APIs.
  • Read-heavy traffic.

3️⃣ Application/Service Caching

🔧 What is it?

Application caches data internally.

📂 Key Types

  • In-Memory Cache
  • Database Cache

✅ Example: Redis Cache

$cacheKey = "user_profile_123";
$data = $redis->get($cacheKey);

if (!$data) {
    $data = fetchUserProfileFromDB(123);
    $redis->set($cacheKey, json_encode($data), 3600); // Cache for 1 hour
}
return $data;

🚨 When to Use

  • Frequently accessed data.
  • Expensive queries.

4️⃣ HTTP Caching Headers

🔧 What is it?

HTTP headers guide caching.

🔗 Important Headers

  • Cache-Control
  • ETag
  • Last-Modified

✅ Example: Conditional Requests

1. Initial Request:

GET /profile/123
ETag: "v1.0"

2. Later request:

GET /profile/123
If-None-Match: "v1.0"

3. If data unchanged:

304 Not Modified

🚨 When to Use

  • Periodically changing data.
  • Reducing bandwidth.

📊 Comparison

Strategy Stored Where? Use Case Benefit
Client-Side Browser/App Product Lists Fastest
Server-Side CDN/Proxy News Feeds Global scale
Application API service User Profiles App level control
HTTP Headers Everywhere User Avatars Flexible

🎯 Choosing Strategy

Requirement Best Fit
Speeding up static data Client-Side Cache
Global caching CDN
Speeding up dynamic data Application Cache
Flexible caching HTTP Headers

✅ Best Practices

1️⃣ Cache What Makes Sense

Cache frequently accessed data.

2️⃣ Set Expiry Times

Short TTL for fast-changing data.

3️⃣ Invalidate Wisely

Invalidate cache on data changes.

4️⃣ Leverage HTTP Headers

Set Cache-Control, ETag.

5️⃣ Monitor Performance

Log cache hits vs misses.

⚠️ Common Mistakes

Mistake Risk
Caching Sensitive Data Data leak
No Expiry Set Stale data
Overcaching Outdated info
Not Invalidating Incorrect data

📣 Conclusion

Smart caching = Faster, Cheaper, Better APIs