justinrainbow/json-schema
A PHP library for validating JSON data against JSON Schema definitions, supporting Draft-3, Draft-4, Draft-6, Draft-7, and Draft 2019-09. Install via Composer to validate payloads and catch structural or schema errors.
Architecture fit. A framework-agnostic, pure-PHP library with no Laravel coupling — no service provider, no facade, no config file. That is the right shape for a validation concern: it can sit inside a small adapter layer at the system boundary and be swapped without touching domain code. Licensing (MIT) is unproblematic. Its natural home is any place the app ingests untrusted structured payloads: webhook receivers, OpenAPI request/response contract checks, config-file validation in CI, event/message schema governance, bulk import pre-flight. It is not a substitute for Laravel's Validator — it validates document shape, not business rules or authorization.
Integration feasibility. High, with one caveat: the ergonomics are library-grade, not framework-grade. The output is an array of {property, message} pairs keyed by JSON-pointer-style paths, which must be mapped to Laravel's dot-notation field errors and human-readable messages. Two other friction points: Validator construction depends on Factory/SchemaStorage, and $ref resolution can perform file and network I/O through UriRetriever — that behavior has to be constrained deliberately rather than inherited by default.
Technical risk.
CHECK_MODE_COERCE_TYPES and CHECK_MODE_APPLY_DEFAULTS rewrite the caller's object in place (explicitly footnoted in the README). Useful for input normalization; dangerous if the same object is later persisted as the raw audit record.format is a hygiene check, not a security control.CHECK_MODE_STRICT is limited to Draft-6/7/2019-09, and CHECK_MODE_NONE is deprecated. Semantics change with flags, so flags must be explicit and pinned.Key questions. Which JSON Schema draft is our org standard today, and is 2020-12/OpenAPI 3.1 on the roadmap? Are schemas trusted (in-repo, code-reviewed) or user-supplied — the latter turns $ref retrieval into an SSRF/DoS surface? Do we want coercion and defaults at the edge, or strict rejection with normalization handled elsewhere? Who owns schema versioning and the error-message catalogue?
Stack fit. Works cleanly on Laravel 9–11 / PHP 8.1+. Do not call the library directly from controllers. Wrap it in four owned artifacts: a JsonSchemaValidator service (single entry point, flags fixed at construction), a SchemaRepository (loads schemas from resources/schemas, caches decoded stdClass trees, resolves $ref only against a pre-registered URI map — never the network), a JsonSchemaValidationException that renders to Laravel's standard 422 JSON shape, and a thin jsonschema validation rule plus a FormRequest macro for day-to-day ergonomics. Register it all in one dedicated service provider; bind the repository as a singleton so schema parsing happens once per process, not once per request.
Migration path. Purely additive — nothing existing is replaced. Sequence:
Compatibility. Composer constraints are permissive; the changelog shows transitive pins (e.g. mark-mabe/php-enum ^4.4) and PHP-version matrix changes, so lock the draft and flags per call to prevent an upgrade from silently altering semantics. Verify the package's PHP 8.x ceiling against our runtime before committing. Under Octane, confirm the schema cache is read-only and process-safe; do not let request-scoped state leak across workers.
Sequencing with schema authoring. Schemas must be treated as code: versioned in-repo, linted in CI with CHECK_MODE_VALIDATE_SCHEMA, and gated by the fixture corpus. Land that discipline before runtime enforcement, otherwise the integration ships a validator whose contract nobody has verified.
Maintenance. Low-to-moderate. Release cadence has been steady (6.6 → 6.11 in the changelog window) with automated changelog and release workflows, CI, and named active maintainers — a healthier signal than the star count. Budget roughly 1–2 days per quarter for dependency bumps plus a compliance re-check (re-run Bowtie for the drafts actually in use after each minor). Pin to a minor version, let Renovate/Dependabot open PRs, and require the fixture corpus as the merge gate.
Support. No commercial backing; community issues only. Internal ownership must be explicit and named: the wrapper, the schema registry, and the error-message catalogue are all our code, not the vendor's.
Scaling. Validation cost is CPU-bound and scales with payload size × schema complexity. Three pathological risks: deeply nested oneOf/anyOf chains, unbounded $ref recursion, and remote $ref fetching. Mitigate by capping payload size before validation, bounding schema depth, restricting resolution to registered URIs only, warming schema parsing at boot, and pushing bulk/batch validation to queued jobs above a size threshold rather than doing it inline on the request path.
Failure modes to design for.
format — keep explicit business validation; schema validation is a contract check, not a security boundary.Ramp-up. Half a day for a mid-level PHP developer to be productive from the README examples. Two to three days to be genuinely proficient with Factory/SchemaStorage/flag semantics and $ref scoping. The steeper, under-budgeted curve is JSON Schema literacy itself — $id scoping, unevaluatedProperties, draft differences — for whoever authors schemas. Standardize on one draft across teams early; a schema-language diaspora is the most likely long-term cost of this adoption.
How can I help you explore Laravel packages today?