Skip to content
beginner Phase 2 · HTTP Deep Dive

HTTP Methods: GET, POST, PUT, DELETE and More

Comprehensive guide to HTTP methods including GET, POST, PUT, DELETE, PATCH, OPTIONS, and HEAD with practical PHP examples.

45m
0 problems
Topic Progress 0%

GET, POST, PUT, DELETE Methods

Overview of HTTP Methods

Method Purpose Idempotent Safe Has Body
GET Retrieve data Yes Yes No
POST Create new resource No No Yes
PUT Replace entire resource Yes No Yes
DELETE Remove resource Yes No Yes
PATCH Partial update No No Yes
OPTIONS Get allowed methods Yes Yes No
HEAD Get headers only Yes Yes No

Idempotent: Making the same request multiple times produces the same result.
Safe: The method does not modify server-side resources.

GET - Retrieve Data

GET requests fetch data without modifying anything. Parameters go in the URL.

<?php
// PHP handling GET request
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    $productId = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
    $category = $_GET['category'] ?? 'all';
    $page = max(1, (int)($_GET['page'] ?? 1));
    $limit = min(100, max(1, (int)($_GET['limit'] ?? 20)));

    // Build query - parameters are visible in URL
    // GET /api/products?category=electronics&page=2&limit=20

    $products = fetchProducts($category, $page, $limit);

    header('Content-Type: application/json');
    echo json_encode([
        'total' => count($products),
        'page' => $page,
        'products' => $products
    ]);
}

When to use GET:

  • Viewing product pages
  • Search results
  • API read operations
  • Any operation that doesn't change server state

POST - Create New Resource

POST sends data to create a new resource on the server.

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $contentType = $_SERVER['CONTENT_TYPE'] ?? '';

    // Handle JSON body
    if (strpos($contentType, 'application/json') !== false) {
        $data = json_decode(file_get_contents('php://input'), true);
    } else {
        // Handle form data
        $data = $_POST;
    }

    // Validate required fields
    $required = ['name', 'price', 'sku'];
    foreach ($required as $field) {
        if (empty($data[$field])) {
            http_response_code(400);
            echo json_encode(['error' => "Missing field: $field"]);
            exit;
        }
    }

    // Create the product
    $productId = createProduct($data);

    http_response_code(201); // Created
    header('Content-Type: application/json');
    header('Location: /api/products/' . $productId);
    echo json_encode([
        'id' => $productId,
        'message' => 'Product created successfully'
    ]);
}

PUT - Replace Resource

PUT replaces the entire resource with the new data.

<?php
if ($_SERVER['REQUEST_METHOD'] === 'PUT') {
    $productId = (int)$_GET['id'];
    $data = json_decode(file_get_contents('php://input'), true);

    // PUT requires ALL fields - partial updates use PATCH
    // If a field is missing, it becomes null/default
    $product = [
        'id' => $productId,
        'name' => $data['name'] ?? '',
        'price' => $data['price'] ?? 0.00,
        'description' => $data['description'] ?? '',
        'status' => $data['status'] ?? 1,
        'sku' => $data['sku'] ?? ''
    ];

    // Validate - all required fields must be present
    if (empty($product['name']) || empty($product['sku'])) {
        http_response_code(400);
        echo json_encode(['error' => 'All fields are required for PUT']);
        exit;
    }

    updateProduct($productId, $product);

    header('Content-Type: application/json');
    echo json_encode(['message' => 'Product replaced successfully']);
}

DELETE - Remove Resource

<?php
if ($_SERVER['REQUEST_METHOD'] === 'DELETE') {
    $productId = (int)$_GET['id'];

    // Check if product exists
    $product = getProductById($productId);
    if (!$product) {
        http_response_code(404);
        echo json_encode(['error' => 'Product not found']);
        exit;
    }

    // Soft delete (mark as deleted)
    deleteProduct($productId);

    http_response_code(204); // No Content
    // No body needed for 204 response
}

PATCH, OPTIONS, HEAD Methods

PATCH - Partial Update

PATCH updates specific fields without sending the entire resource.

<?php
if ($_SERVER['REQUEST_METHOD'] === 'PATCH') {
    $productId = (int)$_GET['id'];
    $data = json_decode(file_get_contents('php://input'), true);

    // PATCH only sends fields to update
    // e.g., {"price": 34.99} - only updates price

    $currentProduct = getProductById($productId);
    if (!$currentProduct) {
        http_response_code(404);
        echo json_encode(['error' => 'Product not found']);
        exit;
    }

    // Merge changes with current data
    $updated = array_merge($currentProduct, $data);

    // Validate only the changed fields
    if (isset($data['price']) && $data['price'] < 0) {
        http_response_code(400);
        echo json_encode(['error' => 'Price cannot be negative']);
        exit;
    }

    updateProduct($productId, $updated);

    header('Content-Type: application/json');
    echo json_encode(['message' => 'Product partially updated']);
}

// PATCH request example:
// PATCH /api/products/123
// Content-Type: application/json
//
// {
//     "price": 34.99,
//     "status": 0
// }
//
// Only price and status are changed. Name, SKU, etc. remain unchanged.

PUT vs PATCH:

  • PUT: Send entire resource: {"name": "Widget", "price": 34.99, "sku": "W001", "status": 1}
  • PATCH: Send only changes: {"price": 34.99}

OPTIONS - Discover Allowed Methods

OPTIONS tells the client what methods and headers are allowed for a resource.

<?php
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    // CORS preflight requests use OPTIONS
    header('Access-Control-Allow-Origin: https://frontend.magento-store.com');
    header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS');
    header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
    header('Access-Control-Max-Age: 86400'); // Cache for 24 hours

    http_response_code(204);
    exit;
}

// Common in Magento for:
// 1. CORS preflight requests from JavaScript
// 2. REST API discovery
// 3. Testing API capabilities

HEAD - Get Headers Only

HEAD is like GET but returns only headers (no body). Used to check if a resource exists.

<?php
if ($_SERVER['REQUEST_METHOD'] === 'HEAD') {
    $productId = (int)$_GET['id'];
    $product = getProductById($productId);

    if ($product) {
        header('Content-Type: application/json');
        header('Content-Length: ' . strlen(json_encode($product)));
        header('Last-Modified: ' . date('r', strtotime($product['updated_at'])));
        http_response_code(200);
    } else {
        http_response_code(404);
    }
    // No body sent
    exit;
}

Method Handler in PHP

<?php
// Centralized method handling
class RequestHandler
{
    public function handle(): void
    {
        $method = $_SERVER['REQUEST_METHOD'];

        switch ($method) {
            case 'GET':
                $this->handleGet();
                break;
            case 'POST':
                $this->handlePost();
                break;
            case 'PUT':
                $this->handlePut();
                break;
            case 'PATCH':
                $this->handlePatch();
                break;
            case 'DELETE':
                $this->handleDelete();
                break;
            case 'OPTIONS':
                $this->handleOptions();
                break;
            case 'HEAD':
                $this->handleHead();
                break;
            default:
                http_response_code(405); // Method Not Allowed
                header('Allow: GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD');
                echo json_encode(['error' => 'Method not allowed']);
        }
    }
}

RESTful API Design with HTTP Methods

Designing RESTful Endpoints

REST (Representational State Transfer) uses HTTP methods to define operations on resources.

Resource-Based URL Design

# Products
GET    /api/products          # List all products
GET    /api/products/123      # Get specific product
POST   /api/products          # Create new product
PUT    /api/products/123      # Replace product entirely
PATCH  /api/products/123      # Update specific fields
DELETE /api/products/123      # Delete product

# Product Images
GET    /api/products/123/images       # List images for product
POST   /api/products/123/images       # Add image to product
DELETE /api/products/123/images/456   # Remove specific image

# Customers
GET    /api/customers                  # List customers
GET    /api/customers/789              # Get specific customer
POST   /api/customers                  # Register new customer
PUT    /api/customers/789              # Update customer profile
DELETE /api/customers/789              # Delete customer

Complete RESTful API Example

<?php
namespace Api\Controller;

class ProductApiController
{
    private ProductRepository $productRepo;

    public function __construct(ProductRepository $productRepo)
    {
        $this->productRepo = $productRepo;
    }

    public function execute(): void
    {
        $method = $_SERVER['REQUEST_METHOD'];
        $id = $this->extractId();

        match($method) {
            'GET' => $id ? $this->get($id) : $this->list(),
            'POST' => $this->create(),
            'PUT' => $this->replace($id),
            'PATCH' => $this->update($id),
            'DELETE' => $this->delete($id),
            default => $this->methodNotAllowed()
        };
    }

    private function list(): void
    {
        $page = (int)($_GET['page'] ?? 1);
        $search = $_GET['search'] ?? null;

        $products = $this->productRepo->search($search, $page);

        $this->jsonResponse(200, [
            'data' => $products,
            'meta' => [
                'page' => $page,
                'total' => $this->productRepo->count($search)
            ]
        ]);
    }

    private function get(int $id): void
    {
        $product = $this->productRepo->find($id);

        if (!$product) {
            $this->jsonResponse(404, ['error' => 'Product not found']);
            return;
        }

        $this->jsonResponse(200, ['data' => $product]);
    }

    private function create(): void
    {
        $data = json_decode(file_get_contents('php://input'), true);

        $errors = $this->validate($data, [
            'name' => 'required',
            'price' => 'required|numeric|min:0',
            'sku' => 'required|unique:products'
        ]);

        if (!empty($errors)) {
            $this->jsonResponse(422, ['errors' => $errors]);
            return;
        }

        $product = $this->productRepo->create($data);

        $this->jsonResponse(201, [
            'data' => $product,
            'message' => 'Product created'
        ]);
    }

    private function replace(int $id): void
    {
        $data = json_decode(file_get_contents('php://input'), true);

        // PUT requires all fields
        $required = ['name', 'price', 'sku', 'status'];
        $missing = array_diff($required, array_keys($data));

        if (!empty($missing)) {
            $this->jsonResponse(422, [
                'error' => 'Missing required fields for PUT: ' . implode(', ', $missing)
            ]);
            return;
        }

        $product = $this->productRepo->replace($id, $data);
        $this->jsonResponse(200, ['data' => $product]);
    }

    private function update(int $id): void
    {
        $data = json_decode(file_get_contents('php://input'), true);

        // PATCH only updates provided fields
        $product = $this->productRepo->update($id, $data);
        $this->jsonResponse(200, ['data' => $product]);
    }

    private function delete(int $id): void
    {
        $this->productRepo->delete($id);
        $this->jsonResponse(204);
    }

    private function jsonResponse(int $code, array $data = []): void
    {
        http_response_code($code);
        header('Content-Type: application/json');
        echo json_encode($data);
    }
}

Magento REST API Methods

Endpoint Method Purpose
/rest/V1/products GET List products
/rest/V1/products/:id GET Get product
/rest/V1/products POST Create product
/rest/V1/products/:id PUT Replace product
/rest/V1/products/:id DELETE Delete product
/rest/V1/carts/mine GET Get customer cart
/rest/V1/carts/mine/items POST Add item to cart
/rest/V1/carts/mine/items/:id DELETE Remove item from cart

Quiz

1. Which HTTP method is used to create a new resource?

Question 1 options

2. What is the difference between PUT and PATCH?

Question 2 options

3. Which HTTP method is used for CORS preflight requests?

Question 3 options

4. What is idempotency in HTTP methods?

Question 4 options

5. What status code should be returned when a POST creates a new resource?

Question 5 options

Flashcards

Question

What are the safe HTTP methods?

Answer

GET, HEAD, OPTIONS, and TRACE are safe methods - they do not modify server-side resources.

Question

What are the idempotent HTTP methods?

Answer

GET, PUT, DELETE, HEAD, OPTIONS, and TRACE are idempotent - making the same request multiple times produces the same result.

Question

When should you use PUT vs PATCH?

Answer

Use PUT when replacing the entire resource (all fields required). Use PATCH when updating only specific fields (partial update).

Question

What HTTP method does a browser use for CORS preflight?

Answer

OPTIONS. Before sending cross-origin requests like PUT or DELETE, the browser sends an OPTIONS request to check if the actual request is allowed.

Question

What status code indicates a resource was created?

Answer

201 Created. Use this for POST requests that successfully create a new resource. Include a Location header with the URL of the new resource.

Question

What status code indicates no content to return?

Answer

204 No Content. Commonly used for DELETE requests where the resource was removed but no response body is needed.

Question

How does Magento use PUT vs PATCH?

Answer

Magento REST API uses PUT for full resource replacement and PATCH for partial updates. For example, PUT /rest/V1/products/:id replaces the entire product, while PATCH updates specific attributes.

Question

What is a RESTful resource?

Answer

A RESTful resource is an entity that can be accessed via standard HTTP methods (GET, POST, PUT, PATCH, DELETE). Examples: products, customers, orders.

Revision Notes

Key Takeaways

  • 1. GET retrieves data and should never modify server state
  • 2. POST creates new resources and is not idempotent
  • 3. PUT replaces entire resources (all fields required)
  • 4. PATCH partially updates resources (only specified fields)
  • 5. DELETE removes resources and should return 204 No Content
  • 6. OPTIONS is used for CORS preflight and API discovery
  • 7. HEAD returns only headers, useful for checking resource existence
  • 8. Idempotent methods: GET, PUT, DELETE, OPTIONS, HEAD

Interview Tips

  • Explain the difference between PUT and PATCH with examples
  • Know which methods are idempotent and safe
  • Describe when to use each HTTP method in a REST API
  • Understand CORS preflight and why OPTIONS is needed
  • Be able to design a RESTful API for a simple e-commerce system

Cheat Sheet

HTTP Methods Cheat Sheet

GET - Retrieve data, safe, idempotent, no body
POST - Create new resource, NOT idempotent, has body
PUT - Replace entire resource, idempotent, requires ALL fields
PATCH - Partial update, NOT idempotent, only changed fields
DELETE - Remove resource, idempotent, returns 204
OPTIONS - Get allowed methods, used for CORS preflight
HEAD - Get headers only, no body

Status Codes:

  • 200 OK (GET, PUT, PATCH success)
  • 201 Created (POST success)
  • 204 No Content (DELETE success)
  • 404 Not Found (resource doesn't exist)
  • 405 Method Not Allowed (invalid method)

Magento REST API:
GET /rest/V1/products - List
GET /rest/V1/products/:id - Get one
POST /rest/V1/products - Create
PUT /rest/V1/products/:id - Replace
DELETE /rest/V1/products/:id - Remove