hadesarchitect/json-schema-bundle
A Symfony bundle for integrating JSON Schema into your application. It helps validate JSON data against schemas and organize schema-based validation through Symfony services and configuration, making JSON payload checks easier to reuse.
Verdict up front (updated for v1.0.0): still not a Laravel package, and still should not be installed into a Laravel application. hadesarchitect/json-schema-bundle remains a Symfony bundle that wires Justin Rainbow's json-schema validator into Symfony's DI container and config tree. v1.0.0 changes the packaging, not the architecture: dependency bumps, vendor-namespaced service/parameter IDs, disabled tests for EOL PHP/Symfony, and an MIT license. There is no Laravel service provider, no Illuminate contract, no facade, no config publishing, no artisan surface — none of which the release notes claim. Its value to a Laravel/PHP team is unchanged: a reference design and a pointer to the underlying validator, not a dependency.
What v1.0.0 actually changes (and why it doesn't move the verdict).
| Release note | Read | TPM impact |
|---|---|---|
| Updated dependencies to latest stable versions | Scope undefined; for a 2016-origin bundle "latest stable" plausibly means Symfony 3.4/4.4 LTS, not 6/7 | Unverified. Does not establish Laravel 9–11 compatibility; must read composer.json before any claim |
| Disabled tests for obsolete PHP and Symfony | Removed dead CI matrix entries | Neutral. Evidence of tidying, not of a supported-version commitment |
| Switched to vendor-based service and parameter names | DI service IDs now vendor-prefixed | Breaking for Symfony consumers — any app overriding hadesarchitect_json_schema.* IDs or params must update. Irrelevant to Laravel |
| Added license (MIT) | Removes prior licensing ambiguity | Genuine, if modest, positive: supply-chain legal review gets easier |
The 1.0.0 version number is a semver statement from the maintainer, not evidence of modernization. Treat it as "the project was tagged," not "the project is maintained."
Architecture fit. Unchanged. Laravel has no bundle equivalent: no Bundle class registration, no Extension::load() config tree, no Resources/config/services.yml auto-discovery, no compiler passes. The v1.0.0 rename actually moves the package further from anything transferable — the only diff a Laravel team would see is different strings in a Symfony container definition. The transferable artifacts remain (a) the ~200–400 lines of glue that construct a validator, resolve a schema, and map violations to a framework error response, and (b) the config shape (schema directory, default draft, cache toggle). The real payload is justinrainbow/json-schema, still in low-maintenance status; the active ecosystem is opis/json-schema (draft 2019-09 / 2020-12, $ref handling, better performance).
Integration feasibility — still low to impossible. Two blockers survive v1.0.0:
symfony/http-foundation, symfony/console, symfony/process, symfony/routing, symfony/error-handler at ^6.x/^7.x. The bundle constrains symfony/framework-bundle and symfony/dependency-injection to a 2.x/3.x/4.x-era range. "Updated dependencies" almost certainly means "updated to the newest version of that era." Composer will still refuse to resolve; forcing it with --ignore-platform-reqs, replace, or a path repo yields a fragile install that breaks on the next composer update. Verify the actual constraints — this is the single highest-value five-minute check.Stringable/implicit nullable parameters. The test-matrix cleanup is weak evidence that newer PHP is now exercised, not proof. Pin down the highest PHP version in .travis.yml/phpunit.xml/CI config before assuming graceful degradation.Extracting the pattern (schema path config → validator service → violation-to-response mapping) remains highly feasible and is where the value sits.
Technical risk. Marginally improved on legal grounds, unchanged on engineering grounds. Still a low-adoption dependency (previously 12 stars, 0 dependents — recheck, since a 1.0.0 tag sometimes attracts a few), single historical maintainer, no advisory triage, no CVE response path, no demonstrated release cadence (one tag is not a cadence). v1.0.0 adds a new migration risk for existing consumers: the service/parameter rename is a breaking DI change that will fail at container compile time, not at runtime, which is at least loud — but it lands on anyone who upgrades casually. Supply-chain risk is asymmetric as before: JSON Schema validation frequently sits on the untrusted-input boundary (webhook ingestion, API payloads, queue messages), so an unpatched validator there is a security-control gap, not a convenience gap. Secondary risks unchanged: draft-04-only semantics will silently mis-handle 2019-09/2020-12 keywords (unevaluatedProperties, dependentRequired, $defs), and remote $ref resolution puts network I/O in the validation hot path.
Key questions for the team (revised):
composer.json. What Symfony and PHP constraints does it actually declare? If it still caps at Symfony 4.x or PHP 7.x, the Laravel question is closed and the assessment is final. (5 minutes, do this first.)FormRequest, custom ValidationRule, job middleware).hadesarchitect_json_schema.* service or parameter IDs? The v1.0.0 rename will break those overrides — decide now whether that upgrade is part of a decommissioning path or a dead end worth skipping.Stack fit. Do not adopt this bundle. Adopt opis/json-schema v2 (or justinrainbow/json-schema only if draft-04 lock-in is absolute and you accept maintenance-mode upstream) and implement the bundle's design idiomatically in Laravel:
JsonSchemaRule implementing Illuminate\Contracts\Validation\ValidationRule for field-level use inside FormRequest/Validator.ValidateJsonSchema middleware for whole-payload validation at the HTTP boundary, throwing ValidationException so Laravel's existing 422 handling and formatting applies.SchemaRepository service resolving schema names to files, caching compiled schemas, bound in a ServiceProvider — this replaces the bundle's Extension config tree.ViolationMapper converting validator output into our public error contract, so library message wording never leaks to clients.If the org genuinely needs a shared package consumed by both a Laravel app and a Symfony app, build a thin internal library wrapping opis and ship both a Laravel ServiceProvider and a modern Symfony bundle. Do not resurrect a Symfony 2-era bundle to achieve that symmetry — and note that v1.0.0's DI rename makes the resurrected artifact less stable, not more.
Migration path. For a Laravel app: greenfield, not migration. For a legacy Symfony service on this bundle, v1.0.0 introduces a fork in the road:
hadesarchitect_json_schema.* service/parameter IDs, update them, then verify container compilation in CI before merging. Do not fold this into an unrelated release.Either way, the decommissioning sequence is unchanged: inventory schemas referenced by bundle config → move to a versioned shared repo with CI validation → swap to opis behind a draft-04 compatibility shim → replace bundle config with environment/config-driven settings → retire app and bundle together. Do not run both validators on the same payloads "for safety"; you will get divergent accept/reject decisions and won't know which is authoritative.
Compatibility.
| Concern | This bundle (v1.0.0) | Recommended (opis/json-schema v2) |
|---|---|---|
| Laravel 9–11 | ✗ No Illuminate integration (architecture, not versioning) | ✓ |
| Composer resolution under Laravel | ✗ Expected conflict on Symfony constraints — verify | ✓ |
| PHP 8.1–8.3 | ? Unverified; test cleanup is weak evidence | ✓ |
| Symfony 6/7 | ✗ Almost certainly out of range for a 2016-origin bundle | ✓ (standalone) |
| Symfony 2/3/4 (legacy consumer) | ✓ with breaking DI-ID rename at v1.0.0 | ✓ |
| Draft-04 | ✓ | ✓ (compat mode) |
| Draft 2019-09 / 2020-12 | ✗ | ✓ |
| License | ✓ MIT as of v1.0.0 (was ambiguous) | ✓ MIT |
| Maintained | ? One tag ≠ cadence; single maintainer; no advisory path | ✓ |
| Adoption signal | Low (previously 12 stars, 0 dependents — recheck) | Broad |
Rows marked ✗ or ? are inferences from release notes, not from composer.json. Confirm before treating any column as final.
Sequencing.
composer.json + CI config (1 hour, blocking). Settles the Symfony/PHP constraint questions and closes or reopens the whole evaluation. Cheap enough that skipping it is negligence.opis/json-schema against three real payloads, including one adversarial case, in a throwaway branch (2–3 days). Measure latency and memory with the largest schema we own.Maintenance. Unchanged in substance, with one item retired: the license ambiguity is gone, so legal/security review of the dependency is now straightforward. Everything else stands — if adopted, this package is an internally-owned fork on day one, requiring a named owner, a pinned commit or vendored copy, and a documented patch procedure. A single 1.0.0 tag does not alter that: there is still no evidenced release cadence, no roadmap, and one historical maintainer. The recommended path (own ~500 lines of Laravel glue, depend on opis) keeps maintenance proportional to our own code and offloads spec compliance to a maintained project.
Support. No upstream support channel, no issue triage, no release cadence demonstrated. Escalation for a validation bug becomes "read the source" — acceptable for a 300-line adapter, unacceptable for a spec-conformance engine on an input boundary. Budget internal SME time regardless of choice: someone must be able to answer "why did this payload fail?" without a vendor.
Scaling. Unchanged; validation cost scales with schema complexity × payload size × request rate, not user count.
$ref. Any schema resolving refs over the network turns validation into an outbound HTTP call inside the request or job path. Ban remote refs in production or resolve behind a cached, allowlisted resolver — this is also an SSRF surface if refs come from untrusted schema sources.pattern regex backtracking. Pathological regexes are a CPU exhaustion vector. Review pattern usage the way we review user-facing regex.Failure modes. Each needs a decided policy, not a default:
$ref timeout → latency spike or 500s. Ban remote refs or cache aggressively.Ramp-up. Unchanged. The code is trivial; the domain is not. Expect 2–3 engineer-days to become productive with the library and its violation output, and 1–2 weeks for the team to internalize JSON Schema semantics well enough to author and review schemas safely — particularly draft differences, additionalProperties interaction with allOf, and format being annotation-only by default rather than enforced. The dominant ramp-up cost is schema governance and the public error contract, both org/process work that neither the bundle nor its v1.0.0 release does anything to reduce. Plan adoption as a governance project with a small code component, not the reverse.
How can I help you explore Laravel packages today?