http clients and apis

HTTP Fundamentals

Every HTTP exchange has a request and a response. The client sends a method, URL, headers, and sometimes a body. The server replies with a status code, headers, and usually a body.

Request line

The request line tells the server what the client wants to do and where.

GET /api/products/42 HTTP/1.1

In a PHP app, the method and path often arrive through $_SERVER.

PHP example
<?php

declare(strict_types=1);

$method = 'GET';
$path = '/api/products/42';

echo $method . ' ' . $path . PHP_EOL;

// Prints:
// GET /api/products/42

In a real request, the path may include a query string such as /api/products?search=keyboard&page=2. The path identifies the resource; the query string usually carries filtering, sorting, pagination, or search values.

Methods have meaning

HTTP methods describe the kind of action the client is asking for.

GET reads a resource. It should not create orders, send emails, delete records, or do other state-changing work.

POST usually creates something or submits a command.

PUT commonly replaces a resource.

PATCH commonly updates part of a resource.

DELETE deletes a resource.

These are conventions, but they matter. They affect caching, retries, API design, browser behaviour, and how other developers understand the system.

PHP example
<?php

declare(strict_types=1);

function methodPurpose(string $method): string
{
    return match ($method) {
        'GET' => 'read',
        'POST' => 'create or submit',
        'PUT' => 'replace',
        'PATCH' => 'partial update',
        'DELETE' => 'delete',
        default => 'unknown',
    };
}

echo methodPurpose('PATCH') . PHP_EOL;

// Prints:
// partial update

Headers describe metadata

Headers carry metadata about the request or response. Common examples:

  • Content-Type: what format the body uses
  • Accept: what format the client wants back
  • Authorization: credentials for the request
  • User-Agent: client information
  • Cache-Control: caching instructions
PHP example
<?php

declare(strict_types=1);

$headers = [
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
];

echo $headers['Content-Type'] . PHP_EOL;

// Prints:
// application/json

Header names are case-insensitive, but it is still worth being consistent in your code and documentation.

Bodies carry data

Many POST, PUT, and PATCH requests include a body. For JSON APIs, the body is usually JSON:

{
  "name": "Keyboard",
  "price": 99.99
}

PHP form submissions commonly populate $_POST. Raw JSON bodies are usually read from php://input and decoded with json_decode().

Responses have status codes

Status codes tell the client how the request went.

PHP example
<?php

declare(strict_types=1);

function statusMeaning(int $status): string
{
    return match (true) {
        $status >= 200 && $status < 300 => 'success',
        $status >= 300 && $status < 400 => 'redirect',
        $status >= 400 && $status < 500 => 'client error',
        $status >= 500 && $status < 600 => 'server error',
        default => 'unknown',
    };
}

echo statusMeaning(404) . PHP_EOL;

// Prints:
// client error

Common API statuses include:

  • 200 OK: successful response
  • 201 Created: a resource was created
  • 204 No Content: success with no response body
  • 400 Bad Request: malformed or invalid request
  • 401 Unauthorized: authentication is missing or invalid
  • 403 Forbidden: authenticated but not allowed
  • 404 Not Found: resource or route not found
  • 409 Conflict: request conflicts with current state
  • 422 Unprocessable Content: validation failed
  • 429 Too Many Requests: rate limit hit
  • 500 Internal Server Error: unexpected server failure

HTTP is stateless

HTTP does not remember previous requests by itself. State comes from cookies, sessions, tokens, databases, caches, and application code.

This is why APIs often send an Authorization header on every request, and browser apps send cookies on every request.

What to check in a project

Check that read actions use GET and state-changing actions do not.

Check that request bodies match the declared Content-Type.

Check that API responses use status codes that match the outcome.

Check that errors return useful, safe messages without leaking secrets or stack traces.

Check logs for enough request information to debug failures: method, path, status, request ID, and timing.

What you should be able to do

After this lesson, you should be able to describe the parts of an HTTP request and response, choose sensible methods and status codes, explain what headers are for, and recognise why statelessness matters in PHP applications and APIs.

Practice

Task: Describe HTTP Exchanges

Write a small PHP script that describes a few HTTP request/response examples.

Requirements

  • Use declare(strict_types=1);.
  • Create a function that accepts method, path, and status code.
  • Return a short sentence describing the exchange.
  • Include a successful GET.
  • Include a created POST.
  • Include a client error such as 404.
  • Print the results.

Check Your Work

Run the script and confirm the output distinguishes methods and status-code groups.

Show solution

This solution classifies the response status and includes the method and path so the full exchange is visible.

PHP example
<?php

declare(strict_types=1);

function statusGroup(int $status): string
{
    return match (true) {
        $status >= 200 && $status < 300 => 'success',
        $status >= 300 && $status < 400 => 'redirect',
        $status >= 400 && $status < 500 => 'client error',
        $status >= 500 && $status < 600 => 'server error',
        default => 'unknown',
    };
}

function describeExchange(string $method, string $path, int $status): string
{
    return $method . ' ' . $path . ' returned ' . $status . ' (' . statusGroup($status) . ')';
}

echo describeExchange('GET', '/api/products/42', 200) . PHP_EOL;
echo describeExchange('POST', '/api/products', 201) . PHP_EOL;
echo describeExchange('GET', '/api/missing', 404) . PHP_EOL;

// Prints:
// GET /api/products/42 returned 200 (success)
// POST /api/products returned 201 (success)
// GET /api/missing returned 404 (client error)

Why This Works

The examples show a read request, a create request, and a missing resource. That gives enough variety to practise method, path, and status-code meaning together.