rushing/laravel-data-schemas
Define structured data schemas in Laravel with a fluent API, helping you validate, cast, and transform data consistently across requests, models, and APIs. Lightweight, expressive, and easy to integrate.
Architecture fit. The package occupies a narrow seam: it reads declared Spatie Laravel Data classes and emits JSON Schema. That is a build-time projection, not a request-path dependency, so it is architecturally low-risk to trial and easy to isolate — it can be removed in a branch with no runtime fallout. It fits where Data classes are already the boundary contract (HTTP request/response bodies, AI tool inputs/outputs, event payloads, generated frontend types) and where one declaration is meant to drive schema, docs, and client types. The explicit doctrine — a declared Data class is the input, always — makes output deterministic and reproducible from source. The corollary is equally important: the package offers nothing for teams that still pass ad-hoc arrays or infer shapes from docblocks/runtime samples. In a TPM frame, this is a downstream enabler, not a driver; its value is strictly conditional on an existing standardization on Data classes.
Integration feasibility. Plausible but unproven. There is no evidence in the available material of an artisan command, a programmatic generator API, config publishing, or output-directory conventions. With 1 star and 0 dependents there is no public production record. Treat feasibility as "plausible pending spike": confirm the command/API surface, supported Spatie Data versions, PHP/Laravel bounds, and JSON Schema draft target before committing any roadmap slot. The integration itself (install package, point at Data classes, generate in CI) is simple in principle; the unknown is whether the projection and tooling are mature enough to wire in without surprises.
Technical risk. High, concentrated in maturity rather than concept:
exists, unique, DB-backed Rule::in, and closure rules cannot be faithfully projected into JSON Schema. If they are dropped silently, the schema under-specifies validation — a correctness risk that must be verified and, if present, documented as a known gap.required, unions, enums, nested/recursive DataCollection, and Optional all need explicit mapping decisions. Divergence here is where drift bugs live.Key questions. (To be resolved in a 1–2 day spike, not by reading alone.)
composer.json?#[Required], #[Max], #[Email]) and the rules() method, or only one — and what happens to rules it cannot represent?DataCollection, enums, unions, Optional, and recursive types projected?$defs/definitions with $ref, or inline everything?Stack fit. Best fit is a Laravel 10/11 + PHP 8.1+ codebase already standardized on Spatie Laravel Data, where Data classes are the single declaration point for boundary shapes. There the package converts an existing convention into a second artifact (JSON Schema) at near-zero marginal cost. In codebases without that convention, the adoption cost is really the cost of migrating to Data classes — the package is downstream of that decision, not a driver. Do not let a package evaluation smuggle in a Data-class migration.
Migration path. Do not migrate anything for this package. Sequence:
vendor/, check the vendored repo's AGENTS.md before editing through — relevant if we patch in place rather than fork.Compatibility. Primary surface is Spatie Laravel Data version alignment; secondary is the JSON Schema draft consumed downstream (API docs tooling, frontend validators, AI SDKs). Pin both explicitly. Treat any Spatie Data minor bump as requiring a schema-regeneration diff in CI. If downstream consumers expect draft-07 (common in OpenAPI 3.0 tooling) and the package emits 2020-12, that translation is ours to own.
Sequencing.
Maintenance. Low runtime maintenance, moderate artifact maintenance. The code runs at build/CI time — no servers, queues, or migrations. Real upkeep is (a) regenerating schemas when Data classes change, (b) tracking Spatie Data upgrades, and (c) owning the package if it stalls. With 0 dependents, assume we are the de facto maintainer of any fork; budget a small ongoing allocation, not zero. The package's own convention applies if we vendor: check the vendored AGENTS.md before editing through.
Support. MIT license, no commercial support, no active-community evidence. Escalation path is "read the source" — acceptable for a small, single-purpose package; unacceptable for a critical contract-generation dependency without a fork plan. Make this explicit in the adoption record so stakeholders understand the support posture rather than discovering it during an incident.
Scaling. Generation cost scales linearly with the number of Data classes and graph depth; for typical applications this is seconds, not minutes, and is entirely CI-side. The real scaling concern is organizational: as the number of Data classes grows, so does the surface that must be regenerated and diffed, so the CI drift check and stable output ordering become essential. Downstream, generated schemas scale well — static artifacts consumable by docs, clients, and AI tool registries.
Failure modes.
exists/unique/DB-backed/closure rules cannot be projected; if dropped without warning, the schema under-specifies validation. Mitigation: verify in spike; maintain an explicit "not representable in JSON Schema" allowlist and document it.required, nullable vs type unions, enum representation, recursion. Mitigation: fixture tests per construct, reviewed by the owner of the downstream consumer.Ramp-up. Engineering ramp-up is modest but not zero: the team must understand Spatie Data attributes, the mapping semantics to JSON Schema (especially required/nullable/Optional), and the drift expectations in CI. Budget roughly a day to run the spike, a sprint to productionize CI generation and golden files for one domain, and a follow-on increment to add the Data-class architecture test. The TPM gate is simple: only greenlight past the pilot if projection fidelity is exact on the nastiest real Data class — otherwise treat it as a reference implementation to borrow from, not a dependency to schedule around.
How can I help you explore Laravel packages today?