Plain, immutable classes
An input DTO is a #[Input] class whose constructor parameters are its fields — a final readonly class, no base class to extend. The factory calls the constructor once the whole input is valid.
Turn HTTP input into immutable, strictly typed objects built through their constructor — validated, cast and processed by attributes.
use Solo\Input\Attributes\{Generator, Input, Validate};
use Solo\Input\Attributes\Source\FromRoute;
#[Input]
final readonly class UpdateProductInput
{
public function __construct(
// PUT /products/{id}
#[FromRoute]
#[Validate('required|integer|exists:products,id')]
public int $id,
#[Validate('required|string|max:255')]
public string $name,
#[Validate('required|numeric|min_value:0')]
public float $price,
#[Generator(UuidGenerator::class)]
public string $revision,
#[Validate('integer|min_value:0')]
public int $stock = 0,
) {
}
}
$input = $factory->fromBody(UpdateProductInput::class, $request, route: ['id' => $productId]);
$input->id; // int — from the URL path
$input->name; // string — from the body
$input->price; // float — cast without loss
$input->revision; // string — generated
$input->stock; // int — 0 when the client left it outcomposer require 'solophp/input:^1.0@RC'1.0 is a release candidate: the API may still change before 1.0.0.
Requirements: PHP 8.3+, a PSR-7 implementation, a validator implementing Solo\Contracts\Validator\ValidatorInterface.