Skip to content

Request

Viames Marino edited this page Mar 26, 2026 · 4 revisions

Pair framework: Request

Pair\Api\Request is the HTTP wrapper used by Pair API controllers.

It covers:

  • method and header access
  • lazy JSON body parsing
  • query parameter access
  • lightweight validation rules
  • bearer token and idempotency-key extraction
  • trusted-proxy-aware client IP resolution

Main methods (deep dive)

1) Basic accessors: method(), header(), query(), all()

Use these when the controller needs to inspect the request shape quickly.

$method = $this->request->method(); // GET, POST, PUT...
$auth = $this->request->header('Authorization');
$contentType = $this->request->header('Content-Type');
$page = $this->request->query('page', 1);
$allQuery = $this->request->query();

all() merges $_GET and the parsed JSON body, with JSON values taking precedence when the same key exists in both places:

// GET /api/users?page=2 with JSON body {"status":"active"}
$all = $this->request->all();
// ['page' => '2', 'status' => 'active']

2) Body helpers: rawBody(), json(), isJson()

rawBody() reads php://input lazily and caches it.

json() parses the request body as JSON and returns either the whole associative array or a single key:

$body = $this->request->json();
$email = $this->request->json('email');

isJson() checks whether the content type includes application/json.

if (!$this->request->isJson()) {
    \Pair\Api\ApiResponse::error('UNSUPPORTED_MEDIA_TYPE', [
        'expected' => 'application/json',
    ]);
}

Practical note: the current implementation expects the decoded JSON body to be an array. Invalid JSON, empty bodies, or scalar JSON payloads effectively behave like null.

3) Validation: validate() and requireFields()

Supported rules:

  • required
  • string
  • int
  • numeric
  • email
  • bool
  • min:N
  • max:N

Example:

$data = $this->request->validate([
    'email' => 'required|email|max:120',
    'age' => 'int|min:18',
    'newsletter' => 'bool',
]);

Current behavior:

  • validate() returns only validated keys
  • missing optional fields are skipped
  • on error, Pair responds immediately with INVALID_FIELDS
  • validated values are not cast automatically

That last point matters:

  • int accepts digit strings, but you should still cast to (int) yourself
  • bool accepts true, false, 1, 0, '1', '0', 'true', 'false', but it does not cast the result to a PHP boolean for you

Required-only shortcut:

$data = $this->request->requireFields(['email', 'password']);

4) Auth and delivery helpers: bearerToken(), idempotencyKey(), isReplayRequest()

bearerToken() extracts Authorization: Bearer ... when present.

idempotencyKey() supports both:

  • Idempotency-Key
  • X-Idempotency-Key

isReplayRequest() returns true when X-Pair-Replay is 1 or true.

$token = $this->request->bearerToken();
$key = $this->request->idempotencyKey();

if (!$token) {
    \Pair\Api\ApiResponse::error('AUTH_TOKEN_MISSING');
}

Replay-aware example:

if ($this->request->isReplayRequest()) {
    // optional branch for offline queue or retried mobile requests
}

5) ip(): string

ip() returns the effective client IP.

Current behavior:

  • uses REMOTE_ADDR by default
  • trusts Forwarded and X-Forwarded-For only when REMOTE_ADDR belongs to PAIR_TRUSTED_PROXIES
  • supports exact proxy IPs and CIDR ranges in PAIR_TRUSTED_PROXIES
  • prefers the standardized Forwarded header when available

Example .env:

PAIR_TRUSTED_PROXIES=127.0.0.1,10.0.0.0/8,192.168.0.0/16

Example:

$ip = $this->request->ip();
$limiterKey = 'throttle:login:' . $ip;

Secondary behavior

  • rawBody() and json() are lazy and cached.
  • header() handles special server variables such as Content-Type and Content-Length.
  • all() is convenient, but remember that JSON overrides same-named query parameters.

Common pitfalls

  • Assuming JSON is always present on POST, PUT, or PATCH.
  • Forgetting that all() lets JSON override same-named query keys.
  • Treating int or bool validation as automatic type casting.
  • Trusting forwarded headers without configuring PAIR_TRUSTED_PROXIES.

See also: API, ApiResponse, Idempotency, ThrottleMiddleware.

Clone this wiki locally