Apivalk highly focuses SRP and therefore is also in generla designed to be like that. Controllers are invokable, you have a sepearte request and response
SRP (Single Responsibility Principle): Each controller should handle exactly one route and one HTTP method.
Immutable-like Responses: Response objects are designed to be built and returned, rather than modified in place across many layers.
Container Integration: Apivalk supports PSR-11 containers, allowing for easy Dependency Injection in your controllers.
Testing: The framework is built with testability in mind, utilizing interfaces and factories that are easily mockable.
…So for example, lets say our example a car store API./yourfolder/Api/v1/Car/Controller/CreateController.php/yourfolder/Api/v1/Car/Request/CreateCarRequest.php/yourfolder/Api/v1/Car/Response/CreateCarResponse.php
The defining feature of Apivalk is that documentation is code. Instead of writing separate documentation files or annotations, you define your API’s shape using PHP classes (AbstractProperty). This single definition drives:
Input Population: Automatic extraction and type-casting of request data.
Validation: Strict enforcement of data types, ranges, and patterns.
Documentation Generation: Automatic creation of OpenAPI (Swagger) specifications and PHP DocBlocks for IDE support.
Even in PHP 7.2, Apivalk enforces strict type-safety through its Property system. Every incoming piece of data is validated against a schema before it ever reaches your controller.
Apivalk eliminates manual route registration. By using the ClassLocator, the framework discovers your controllers, reads their route metadata, and builds a high-performance routing cache automatically.
The Property system is the engine that powers Apivalk.
Definition: You define a property (e.g., StringProperty) and configure its constraints (minLength, pattern, etc.).
Factory: ValidatorFactory creates the appropriate validator for that property.
Validation: The validator returns a ValidatorResult indicating success or specific error messages.
This system ensures that when you access $request->body()->get('email'), you are guaranteed that the data exists (if required) and matches your constraints.
Apivalk is designed for developer productivity through automation:
Route Discovery: RouterFilesystemCache uses ClassLocator to find all classes extending AbstractApivalkController. It calls getRoute() on each to build the routing table.
Request Population: AbstractApivalkRequest automatically populates itself using metadata from getDocumentation().
Request Validation: RequestValidationMiddleware automatically validates the populated request against the same documentation before the controller is invoked.