0

HTTP request/response cycle — the exact vocabulary of each part

Beginner5 min read·eng-13-001
interview

Concept

HTTP request/response cycle — the exact vocabulary for every component that travels between a client and a server.

Request structure:

  • Request line: METHOD /path HTTP/version — e.g., GET /users/42 HTTP/1.1
  • Headers: Key-value pairs with metadata. Host, Accept, Authorization, Content-Type, Cookie, etc.
  • Empty line: Separates headers from the body.
  • Body (optional): Data sent with the request. Present for POST, PUT, PATCH. Absent for GET, DELETE, HEAD.

Response structure:

  • Status line: HTTP/version STATUS_CODE REASON_PHRASE — e.g., HTTP/1.1 200 OK
  • Headers: Content-Type, Set-Cookie, Location, ETag, Cache-Control, etc.
  • Empty line: Separates headers from body.
  • Body: The actual resource data, HTML, JSON, file, etc.

Key terms:

  • URL (Uniform Resource Locator): scheme://host:port/path?query#fragment
  • URI (Uniform Resource Identifier): The broader concept — URL is a type of URI.
  • Query string: ?key=value&key2=value2 — after the ?.
  • Fragment: #section — processed by the browser only, never sent to the server.
  • Port: Default 80 for HTTP, 443 for HTTPS. Omitted when using the default.

HTTP versions:

  • HTTP/1.1: Persistent connections, chunked transfer encoding. One request per connection at a time.
  • HTTP/2: Multiplexing — many requests over one connection. Header compression (HPACK). Binary protocol.
  • HTTP/3: QUIC transport (UDP-based). Lower latency, especially on lossy connections.

HTTPS: HTTP + TLS. The HTTP protocol is unchanged — TLS encrypts the TCP stream it travels over.

Code Example

php
<?php
// ANATOMY of a raw HTTP request (what goes over the wire)
/*
GET /users/42 HTTP/1.1           ← Request Line: METHOD path HTTP-version
Host: api.example.com            ← Required header in HTTP/1.1
Accept: application/json         ← What the client wants back
Authorization: Bearer eyJ...     ← Auth token
X-Request-Id: 550e8400-e29b-...  ← Trace ID for logging
                                 ← Empty line — headers end here
                                 ← No body for GET
*/

// ANATOMY of a raw HTTP response (what the server sends back)
/*
HTTP/1.1 200 OK                  ← Status Line: HTTP-version STATUS REASON
Content-Type: application/json   ← What the body is
Content-Length: 87               ← Body size in bytes
Cache-Control: max-age=300       ← Caching directive
ETag: "33a64df551425fcc55e4d..."  ← Entity tag for conditional requests
                                 ← Empty line — headers end here
{"id":42,"name":"Alice","email":"alice@example.com"}  ← Body
*/

// Parsing URLs in PHP
$url   = 'https://api.example.com:8080/users?role=admin&page=2#results';
$parts = parse_url($url);
// [
//   'scheme'   => 'https',
//   'host'     => 'api.example.com',
//   'port'     => 8080,
//   'path'     => '/users',
//   'query'    => 'role=admin&page=2',
//   'fragment' => 'results',   ← NOTE: client-only, never reaches PHP
// ]

parse_str($parts['query'], $queryParams);
// ['role' => 'admin', 'page' => '2']

// In Laravel — reading request components
use Illuminate\Http\Request;

Route::get('/users', function (Request $request) {
    $method   = $request->method();           // 'GET'
    $path     = $request->path();             // 'users'
    $fullUrl  = $request->url();              // 'https://api.example.com/users'
    $header   = $request->header('Accept');   // 'application/json'
    $page     = $request->query('page', 1);   // '2' or default 1
    $body     = $request->json()->all();      // parsed JSON body (for POST)
    $ip       = $request->ip();               // client IP
    $isSecure = $request->isSecure();         // true for HTTPS
});

// Sending a response with all components
return response()
    ->json(['id' => 42, 'name' => 'Alice'], 200)           // body + status
    ->header('X-Request-Id', $requestId)                    // custom header
    ->header('Cache-Control', 'private, max-age=60');       // caching