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?
2. What is the difference between PUT and PATCH?
3. Which HTTP method is used for CORS preflight requests?
4. What is idempotency in HTTP methods?
5. What status code should be returned when a POST creates a new resource?
Flashcards
Question
What are the safe HTTP methods?
Click to reveal answer
Answer
GET, HEAD, OPTIONS, and TRACE are safe methods - they do not modify server-side resources.
Question
What are the idempotent HTTP methods?
Click to reveal answer
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?
Click to reveal answer
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?
Click to reveal answer
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?
Click to reveal answer
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?
Click to reveal answer
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?
Click to reveal answer
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?
Click to reveal answer
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