Skip to main content

The Five Controllers

All five are generic over the resource type: @template TResource of AbstractResource. Declare the concrete type via the @extends annotation so static analysis and IDE autocompletion work.

What You Write

Every resource controller implements three things:
  1. getResourceClass(): string — return your resource class name.
  2. A route declaration method — see the table below.
  3. __invoke(ApivalkRequestInterface $request): AbstractApivalkResponse — your business logic.
The base class provides getRequestClass(), getResponseClasses(), and getEmptyResource(). Create and Update also expose a getResource() helper — see below.

Route declaration: buildRoute()

All five resource controllers use buildRoute() — never implement getRoute() directly. The base class provides a final getRoute() that calls your buildRoute() and auto-injects extras: You only declare the URL, path parameters, authorization, pagination, and rate limit in buildRoute().

Examples

Create

View

Update

Delete

List

Implement buildRoute() instead of getRoute(). Tags, filters, and sortings from the resource are injected automatically — declare only the URL, authorization, pagination, and rate limit.

Nested Resources

Because buildRoute() is fully explicit, nested URLs are straightforward — add more path segments and declare each path parameter:
The same pattern extends to any depth. Each ->pathProperty() call documents the parameter in OpenAPI and registers it for validation.

getResource() Helper

AbstractCreateResourceController and AbstractUpdateResourceController expose a typed $this->getResource($request) method that returns a fully populated TResource. Create — body only. Path parameters are intentionally excluded because the identifier doesn’t exist yet (the server generates it after persisting). Update — body fields first, then any path parameter whose name matches a resource property is automatically set. If your route has {animal_uuid} and AnimalResource declares an animal_uuid property, $resource->animal_uuid is already populated after calling getResource(). For nested resources with multiple path params (e.g. {user_uuid}/{authenticator_uuid}), only the ones whose names appear as resource properties are set — parent-scope params are ignored. If you need the raw path value directly without the helper, $request->path()->key always works.

What the Base Class Provides

  • getRequestClass() — returns ResourceRequest::class by default (a shared, empty request class).
  • getResponseClasses() — the mode-appropriate success response + BadRequestApivalkResponse + ForbiddenApivalkResponse.
  • getEmptyResource() — instantiates the resource class returned by getResourceClass(), useful inside buildRoute().

IDE Autocomplete via the DocBlock Generator

After running the docblock generator, a typed request class is generated for each controller that has path parameters, sorting, filtering, or pagination (e.g. AnimalViewRequest, AnimalUpdateRequest, AnimalListRequest). To get full IDE autocomplete in __invoke, add a @param annotation with the generated class:
For Update, the same annotation gives you both typed $request->path() and typed $this->getResource($request):
For List, annotate with AnimalListRequest to get typed sorting(), filtering(), and paginator().