Product Decisions This Supports
- Contract-first API design as a deliberate strategy. If your API surface is already described as JSON Schema (or OpenAPI components), this package is a concrete example of enforcing that schema at the request boundary rather than re-deriving field rules in PHP. It supports a decision to make the schema the single source of truth — with the caveat that you'd re-implement the enforcement in Laravel, not install this bundle.
- Build vs. buy for request validation. The package frames a cheap "buy" — one annotation, schema-checked payloads, structured violations. But because it's a Symfony bundle with no Laravel extension points, the honest framing for a Laravel product is build a small first-party rule (~50–100 lines on top of
justinrainbow/json-schema or opis/json-schema) rather than buy or adapt. That is a one-sprint decision, not a platform investment.
- Roadmap sizing for "strict payload validation." It clarifies scoping: annotating Symfony controllers is trivial; delivering the same guarantee in Laravel — shared rule, error-envelope mapping, schema dialect review, shadow-mode rollout — is a short but real engineering task with a dependency-policy decision attached.
- Error-contract standardization. Consistent schema-violation responses (JSON Pointer paths, RFC 7807
application/problem+json) feed directly into API versioning, deprecation policy, and client-SDK decisions. This is the highest-leverage PM output the pattern enables.
- Supply-chain and risk posture decisions. 4 stars, 0 dependents, score 0.3, no visible CI or maintenance signal, and a Symfony-only architecture that doesn't map to Laravel. This is a clear "adopt the pattern, reject the dependency" call — and a useful precedent for how the team treats abandoned packages touching attacker-controlled input.
- Concrete use cases worth prioritizing: webhook receivers (untrusted third-party payloads), partner integrations, rule/config ingestion endpoints, internal service-to-service JSON, and any endpoint where a malformed body should fail fast before domain logic.
When to Consider This Package
Worth adopting the pattern when:
- You already maintain JSON Schemas for your API surface and want enforcement close to the controller or request boundary.
- Endpoints are simple JSON-in / JSON-out (no multipart, no file uploads).
- Payloads are nested enough that Laravel's
array and dot-notation rules genuinely fall short.
- You're prepared to own the ~100-line implementation, cache compiled schemas, and pin the error contract with tests.
Look elsewhere — or copy the pattern — when:
- You are on Laravel. This is a Symfony bundle; the bundle registration, Doctrine annotation reader, and kernel event listener have no Laravel equivalent. Use
FormRequest + a JSON Schema engine (justinrainbow/json-schema for simplicity, opis/json-schema for better performance and draft-07/2019-09 support) inside a custom Rule or withValidator().
- You need maintenance or security guarantees. Zero dependents and near-zero stars mean no downstream pressure to patch a CVE in a transitive JSON Schema dependency — and this code runs on attacker-controlled input. Do not make it a strategic dependency.
- You need rich field-level error mapping into a custom envelope, or validation of nested files, multipart bodies, or non-JSON content types.
- Performance at high RPS matters. Schema compilation and caching behavior is undocumented; assume you must add your own cache layer regardless.
- Compliance requires maintained dependencies (SBOM, CVE monitoring, provenance). An abandoned 2015–2017-era bundle fails this gate.
Dialect and runtime gates before any decision: confirm the engine supports the JSON Schema draft your schemas are authored in (draft-04 vs draft-07 vs 2019-09 differ materially on exclusiveMinimum, const, and if/then/else), and that it runs on your PHP version (8.1/8.2/8.3) with active security maintenance.
How to Pitch It (Stakeholders)
To executives: This is a tiny MIT-licensed component that enforces JSON contracts at the API edge and removes ad-hoc validation code from controllers. The concept is sound and the cost is near zero — but community adoption is negligible, it has effectively no maintenance signal, and it's built for Symfony, not our Laravel stack. Recommendation: adopt the pattern, not the dependency. A short, low-risk engineering task delivers the same outcome, removes a supply-chain liability, and leaves us owning a small piece of code we fully understand.
To engineering: One annotation plus JSON Schema validation at the controller boundary — in Symfony it drops in cleanly; in Laravel we replicate it with a FormRequest and a schema engine so we don't fight the framework. Plan: spike opis/json-schema against three real payloads (1–2 days) to de-risk dialect coverage; implement a first-party JsonSchema rule that maps violations to the message bag using JSON Pointer keys; wrap in a FormRequest base class that owns 422 shaping and application/problem+json negotiation; run in shadow mode for one release cycle on high-traffic endpoints before enforcement. Operational notes: cache compiled schemas per worker, cap request body size before validation, enforce maxItems/maxDepth to avoid a cheap DoS vector, and order validation after authentication so unauthenticated clients don't burn CPU. Record the decision in the ADR log so the bundle isn't re-proposed.