v3.0.0
Composable attribute API with explicit source bags
A ground-up redesign. #[Field] is split into focused per-concern attributes, route/context get their own bags instead of being merged into the body, and every misconfiguration is caught at metadata-build time.
Breaking release — every DTO needs to be migrated.
Highlights
- 13 single-purpose attributes replace
#[Field]:#[Validate],#[Cast],#[Caster],#[PreProcess],#[PostProcess],#[Generator],#[Items],#[Group],#[Exclude],#[Ignore], plus source attributes#[FromRoute],#[FromContext],
#[FromBody](dot-path). handle()→handleBody()/handleQuery();$routeParamsbecomes named$route+$context. No more silent merge into the body bag.ProcessorInterface::process()now receives aProcessContextDTO ($config,$route,$context) instead of raw arrays.- Structured validation errors:
['field' => [['rule' => 'X', 'params' => [...]], …]]instead of strings. - Nested
#[Items]populates the array with instances of the items Request class (was: raw arrays). - Fail-fast metadata — 18
ConfigurationExceptionfactories surface DTO misuse at build time, naming the offendingClass::$property. - 100% test coverage (213 tests), PHPStan level 8 clean.
Attribute migration
| 2.x | 3.0 |
|---|---|
#[Field(rules: 'X')] |
#[Validate('X')] |
#[Field(mapFrom: 'a.b')] |
#[FromBody('a.b')] |
#[Field(cast: 'int')] |
#[Cast('int')] |
#[Field(cast: MyCaster::class)] |
#[Caster(MyCaster::class)] |
#[Field(preProcess: X)] |
#[PreProcess(X)] |
#[Field(postProcess: X, postProcessConfig: […])] |
#[PostProcess(X, config: […])] |
#[Field(generator: G, generatorOptions: […])] |
#[Generator(G, options: […])] |
#[Field(items: I)] |
#[Items(I)] |
#[Field(group: 'g', mapTo: 'k')] |
#[Group('g', mapTo: 'k')] |
#[Field(exclude: true)] |
#[Exclude] |
Other breaking changes
- Every public non-static property is now managed. For controller-injected state, mark
#[Ignore]or useprotected/privatevisibility. - Route params are no longer merged into body — declare them with
#[FromRoute]. - 2.x silent paths now throw
ConfigurationException:#[Cast(SomeClass)],#[Cast('unknown')],#[Cast]+#[Caster],#[Generator]+companions,#[Items]+#[Cast]/#[Caster], two source attributes on one property, non-static processor methods,
empty-string attribute args.
Requirements
PHP 8.2+, PSR-7 HTTP Message. Recommended validator: solophp/validator.
Full Changelog: v2.2.0...v3.0.0