Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.apivalk.com/llms.txt

Use this file to discover all available pages before exploring further.

Creating a Request

Every request class must extend AbstractApivalkRequest and implement the getDocumentation() method.

Example

namespace App\Http\Request\Pet;

use apivalk\apivalk\Http\Request\AbstractApivalkRequest;
use apivalk\apivalk\Documentation\ApivalkRequestDocumentation;
use apivalk\apivalk\Documentation\Property\StringProperty;
use apivalk\apivalk\Documentation\Property\IntegerProperty;

class CreatePetRequest extends AbstractApivalkRequest
{
    public static function getDocumentation(): ApivalkRequestDocumentation
    {
        $doc = new ApivalkRequestDocumentation();

        // Body parameters — addBodyProperty (body), addQueryProperty (query),
        // addPathProperty (path). `setIsRequired(true)` is the default; call
        // `setIsRequired(false)` to mark a property as optional.
        $doc->addBodyProperty(new StringProperty('name', 'Pet name'));
        $doc->addBodyProperty(
            (new StringProperty('type', 'Species of the pet'))->setIsRequired(false)
        );

        // Path parameters (matched from route like /pet/{id})
        $doc->addPathProperty(
            new IntegerProperty('id', 'Internal ID')
        );

        return $doc;
    }
}

Accessing Data

Data is organized into “Bags”. The framework automatically populates these bags and casts the values to the types defined in your documentation.
public function __invoke(ApivalkRequestInterface $request): AbstractApivalkResponse
{
    // Access body parameters (returns the value directly via magic getter)
    $name = $request->body()->name;
    
    // Access query parameters
    $page = $request->query()->page ?? 1;
    
    // Access path parameters (/user/{id})
    $userId = $request->path()->id;
    
    // Access headers
    $token = $request->header()->Authorization;
    
    // Access uploaded files (returns File object)
    $image = $request->file()->get('avatar');

    // Access populated sorting (as defined in Route). SortBag is iterable —
    // iterate directly. The bag is always populated: if the user does not
    // provide an order_by parameter, it contains the default sorting defined
    // on the route.
    foreach ($request->sorting() as $field => $sort) {
        $isAsc = $sort->isAsc();
    }
}

Magic Getters

ParameterBag supports magic getters for cleaner code:
$name = $request->body()->name;
$userId = $request->path()->id;

Base vs. Runtime Documentation

Every request class exposes two documentation views:
  • StaticRequestClass::getDocumentation(). Returns the base ApivalkRequestDocumentation as declared by the developer. Stable and independent of the route.
  • Instance$request->getRuntimeDocumentation(). Returns the base documentation merged with route-derived metadata (pagination query params, filter fields, order_by, available sort fields). This is what the RequestValidationMiddleware validates against and what the population strategies consume.
You normally only define the base via getDocumentation(). The framework builds the runtime view for you in RequestDocumentationFactory::buildRuntimeDocumentation().

Automatic Request Documentation

When a route has sorting defined or pagination enabled, the framework automatically documents the corresponding query parameters (order_by, page, limit, offset, or cursor) in your OpenAPI specification. This includes:
  • Validation: Ensuring that only allowed values and correct formats are used.
  • Example generation: Showcasing correct usage for sorting and pagination.
  • Default values: Reflecting the configuration defined on the route (e.g., setMaxLimit).
Additionally:
  • The sorting() bag is automatically populated with default values if the user does not provide an order_by parameter.
  • The paginator() object is automatically created and accessible if pagination is enabled.

Validation

Validation happens automatically if you use the RequestValidationMiddleware. If the incoming data does not match your getDocumentation() definition, the framework will immediately return a 422 Unprocessable Entity response with detailed error messages.

Resource Requests

For endpoints backed by a resource CRUD controller you typically don’t author a request class at all — the framework uses a single shared ResourceRequest, and the runtime documentation is derived from your AbstractResource definition. See Resources.

Authentication Identity

You can attach an authentication identity to the request:
$user = $this->authService->authenticate($request);
$request->setAuthIdentity($user);

// Later in controller or middleware
$currentUser = $request->getAuthIdentity();