You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add per-directory schema domains, cache the Opis loader, and expand examples
- Add schemas (path/domain pairs) config option, deprecating the single
schemas_path/schema_domain pair; SchemaValidator::registerSchemaDir()
lets the bundle register its own Examples/Schemas without colliding
with the app's schemas_path on the shared resolver
- Reuse one SchemaLoader/SchemaResolver per SchemaValidator instance
instead of rebuilding it on every validate() call, so long-lived
processes (Swoole/RoadRunner) don't re-parse the same schema on every
request; filters are still re-registered fresh per call
- Split ValidationException (domain) from HttpValidationException (HTTP
transport); extract SchemaFilterResolver and Arrays::toObjectGraph()
- Add a multi-level nested example (order-create -> customer -> name/
email/shippingAddress, with both relative and absolute $ref) and a
custom $error message on the promo code filter
- Add Mermaid diagrams (request flow, schema $ref graph) and a GitHub
Sponsors button to the docs
- Fix numerous documentation inaccuracies against the real API
Copy file name to clipboardExpand all lines: CHANGELOG.md
+34Lines changed: 34 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,6 +5,40 @@ All notable changes to this project will be documented in this file.
5
5
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
8
+
## [4.0.0] - 2026-09-02
9
+
10
+
### Added
11
+
-`schemas` configuration option - an array of `{path, domain}` pairs, replacing the single `schemas_path`/`schema_domain` pair so multiple schema directories (each under their own domain) can be registered at once
12
+
-`SchemaValidator::registerSchemaDir(domain, path)` - public API to register an additional schema directory on the shared resolver after construction; used internally to register the bundle's own `Examples/Schemas/` (and its `common/` subdirectory) without colliding with the app's own `schemas_path`
13
+
-`auto_cast_query` and `auto_cast_path` configuration options (default `true`) to control automatic numeric/boolean casting for query and path parameters independently
14
+
-`HttpValidationException` - HTTP-transport wrapper around the domain `ValidationException`, thrown by `MapRequestResolver` when `#[MapRequest]`'s `triggerResponse` is `true`
15
+
-`SchemaFilterResolver` - extracted service that recursively discovers `$func` filter names declared in a schema's `$filters`
16
+
-`Helpers\Arrays::toObjectGraph()` - the array-to-stdClass-graph conversion previously inlined in `SchemaValidator`
17
+
- Opis `$filters` example (`PromoCodeFilter`) wired into the bundled `/_examples/validation/user` route, including a custom `$error` message
- New `/_examples/validation/order` example route and schema set (`order-create.json`, `customer.json`, `order-item.json`, `common/address.json`, `common/country.json`) demonstrating multi-level nesting with both relative and absolute `$ref`
20
+
- Application-level end-to-end tests exercising the bundle's example routes through a real host application kernel and router (replacing the previous bundle-only synthetic kernel tests)
21
+
- Mermaid diagrams in the documentation: a sequence diagram of the `#[MapRequest]` request/validation/DTO flow, and a dependency graph of the example schemas' `$ref` relationships
22
+
-`.github/FUNDING.yml` and a GitHub Sponsors button in the documentation nav bar
23
+
24
+
### Changed
25
+
-**`ValidationException` is now a plain domain exception** (`extends RuntimeException`, no longer `extends HttpException`) - HTTP concerns are handled exclusively by the new `HttpValidationException`
26
+
-`SchemaValidator` now builds one `SchemaLoader`/`SchemaResolver` per instance and reuses it across calls, instead of a fresh `Validator` (and its underlying schema cache) on every single validation - Opis parses each schema file only once per loader, so long-lived processes (e.g. Swoole/RoadRunner workers) no longer pay the full parse cost on every request. Filters are still re-registered fresh on every call, since a filter's resolved service may not be shared
27
+
- Headers are never auto-cast (previously could be affected by global type casting)
28
+
29
+
### Deprecated
30
+
-`schemas_path` and `schema_domain` configuration options - use `schemas` instead. They still work but emit a deprecation notice
31
+
32
+
### Removed
33
+
- Dead code in `Helpers\Arrays`: `insertInArray`, `toObject`, `groupBy`, `arrayReplaceKeys` (only `sortArrayByKeys` remains, in use)
34
+
- Synthetic bundle-only `TestKernel` and its E2E test suite - replaced by application-level E2E tests (see Added)
35
+
36
+
### Fixed
37
+
- Multiple documentation inaccuracies found to not match the actual implementation: fabricated `ValidatedRequest`/`ValidatedPayload` API in api.md (real `ValidatedRequest` only exposes `getPayload(): Payload`, plus `getViolations()`/`hasViolations()`/`isValid()`/`getStatus()`; `ValidatedPayload` does not exist - the real class is `Payload`), `ValidatedDtoInterface` incorrectly shown as an empty marker interface, fabricated `TrimFilter`/`LowercaseFilter` classes, wrong PHP/Symfony version requirements (was showing PHP 8.4+/Symfony 8.0+; real requirement is PHP >=8.2, Symfony ^7.4|^8.0), wrong `schema_domain` default (was documented as `null`, actually `https://outcomer.dev`), a reproducible bug in a dto-injection.md example (`$query['query']`/`$headers['authorization']` array access on what are actually `object` return types from `Payload::getQuery()`/`getHeaders()`), incorrect error response `message` text (`"Validation failed"` vs actual `"Request data is invalid"`), incorrect `Examples/Model/` path (actual: `Examples/Dto/`), incomplete example routes list (missing `/api-user`, `/order` and `/info`), and incorrect namespace in README.md's quick usage snippet
38
+
- A schema file loaded outside `schemas_path` (e.g. one of the bundle's own examples) with the same filename as a schema inside `schemas_path` would overwrite that directory's registration on the shared resolver, breaking any concurrently-used schema in `schemas_path` for the rest of the process's lifetime - fixed by giving each registered directory its own domain instead of reusing `schema_domain` for both
39
+
- Clarified that the bundle's `/_examples/*` routes ship with their own exception listener and don't require the manual listener setup described in quick-start.md
40
+
- Clarified that importing the bundle's `config/routes.yaml` is only needed when the host app doesn't already auto-discover attribute-routed controllers via `routing.controllers`
0 commit comments