slick/json-api
A lightweight Laravel package for building JSON:API-compliant APIs with resource serialization, relationships, sparse fieldsets, filtering, pagination, and validation error handling—conventions baked in, minimal configuration required.
Architecture fit. slick/json-api remains a framework-agnostic implementation of the JSON:API specification — the changelog URL confirms provenance as github.com/slickframework/json-api, i.e. the Slick micro-framework lineage, built around PSR-7 HTTP messages and PSR-15-style middleware rather than Laravel's Illuminate\Http\Request/Response, service container, and Eloquent. The value proposition (content negotiation for application/vnd.api+json, spec-compliant error objects, pagination links/meta, CRUD semantics for resources and relationships) is still exactly what a Laravel API team would otherwise hand-roll. The fit remains conceptual, not structural. v1.5.1 narrows one gap: schema discovery can now resolve schema objects through a DI container. Laravel's container is PSR-11 compliant, so there is now a legitimate seam where our service-provider bindings can feed the library's schema layer — that is a real, if modest, improvement to the adapter's ergonomics.
Integration feasibility. Feasible but still non-trivial. A working integration requires:
symfony/psr-http-message-bridge + nyholm/psr7 or guzzlehttp/psr7) to convert Laravel requests/responses into and out of the library's message model.errors[].status, code, source.pointer) are preserved rather than re-rendered as Laravel's {message, exception, trace} shape.type, id, attributes, relationships), including sparse fieldsets (fields[articles]=title), compound documents (include=author), sorting, and filtering — none of which the library infers from Eloquent.links/meta pagination contract, and of route-model binding with JSON:API resource identifiers.AppServiceProvider bindings. It does not make the library container-aware in the Laravel sense; it is a resolution hook, not service-provider integration.Technical risk: high, marginally reduced. Two data points from v1.5.1 soften, but do not overturn, the abandonment concern: there is now an observable version step (v1.5.0 → v1.5.1) with a changelog and a GitHub compare link, which is evidence of an active release cadence and of semver discipline (dependency widening shipped in a patch). But the core risk profile is unchanged — small-star, zero-dependent package with a single-maintainer profile, no downstream validation, and an unclassified license (NOASSERTION), which alone remains a distribution and audit blocker until resolved. There is no observable security disclosure process, no CVE history to reason about, and no evidence of CI/coverage in the notes.
Two new risk items introduced by this release:
doctrine/collections constraint moved from a pinned range to ^2.2 || ^3.0, with Symfony components refreshed to latest compatible versions. Constraint widening in a patch release is semver-legal but operationally risky for us: it enlarges the set of resolvable graphs and can pull a transitive major we have not tested. Pin the lockfile and audit composer why doctrine/collections before adopting.The 2026-09-25 release date on the prior version remains a data-quality anomaly — verify on Packagist and compare against the GitHub tag timestamps before anything else.
Key questions.
/articles/1/relationships/author) and related links, not just top-level resources?doctrine/collections constraint widened? Which concrete consumer needed ^3.0, and is the test matrix actually green against both majors?laravel-json-api (Eloquent-native, actively maintained), neomerx/json-api (encoder-only, spec-focused), or spatie/laravel-query-builder plus a thin serializer?Stack fit. Compatible in principle with Laravel 10–12 on PHP 8.2+, but only as a middleware island: it sits in the HTTP layer and knows nothing about Eloquent, policies, or Sanctum. Treat it as a serialization/negotiation engine, not an API framework, and keep all Laravel coupling in code we own. The new container-resolution hook is the one integration point where the library now meets Laravel halfway — use it, but contain it behind our own SchemaRegistry abstraction so it is swappable.
Migration path. Do not attempt a big-bang conversion. Sequence:
doctrine/collections majors, establish maintainer contact. Hard stop if license is unclear.GET collection endpoint behind a feature flag, with the existing API Resource output preserved as the fallback path. Wire schema discovery through the Laravel container here to validate the new capability in a bounded scope.include compound documents.Compatibility. Expect friction in five places: Accept-header negotiation colliding with Laravel's own content negotiation; authentication failures from Sanctum/Passport returning non-JSON:API error bodies unless explicitly wrapped; pagination metadata diverging from LengthAwarePaginator; route-model binding returning numeric IDs where the spec expects resource identifiers; and now a transitive dependency graph that includes Symfony components and either doctrine/collections major, which must be pinned and conflict-checked against the rest of the application.
Sequencing. License and provenance first (week 1), fork-and-vendor under a controlled namespace second, adapter layer plus container-bound schema registry third, contract tests before any production traffic, and a documented exit path to laravel-json-api if the fork proves more expensive than migration. Budget the escape hatch as a scheduled deliverable, not an emergency plan.
Maintenance. Effective maintenance still transfers to us on day one. Pin an exact version and commit the lockfile — the widened doctrine/collections constraint makes floating resolution materially riskier than before. Vendor or fork the source, and treat upstream as low-touch rather than dormant: v1.5.1 shows someone is committing, which is good, but a low release frequency with a single maintainer still means we own breakage. Assign a named owner for the adapter layer and a standing quarterly review of PHP/Laravel minor releases. Estimated steady-state cost: 0.2–0.3 FTE for the bridge and serialization mapping, plus unplanned work on every Laravel major upgrade and on every upstream dependency refresh.
Support. No vendor, no SLA, no security advisory channel, no backport policy. Our team becomes the triage point for any spec-compliance defect. The v1.5.1 changelog is a courtesy, not a support contract. This must be written into the ownership model before the first production deployment, and it must be visible to the security review board given the inability to source third-party patches.
Scaling. The library itself is not the bottleneck — negotiation and serialization are cheap relative to database work. The scaling risks are indirect: compound documents (include) will generate N+1 queries unless eager loading is enforced in the mapping layer; response caching (ETag, Cache-Control, Vary: Accept) is not provided and must be added; and large collections require us to own pagination limits and cursor strategy. Container-resolved schema objects are constructed per-request in the naive case — verify the container binding is a singleton, or schema construction becomes a per-request cost.
Failure modes.
doctrine/collections range resolves differently across environments or after a composer update, producing a bug that is invisible in the lockfile-pinned CI run.Ramp-up. Roughly one to two weeks for a mid-level PHP engineer to become productive, but the real cost is JSON:API specification fluency, not the library's API surface — sparse fieldsets, compound documents, and relationship endpoints are easy to implement incorrectly. The new DI-based schema discovery adds a small amount of container-configuration learning but reduces boilerplate. Budget a short internal spec workshop and designate one engineer as the JSON:API subject-matter owner.
Verdict. v1.5.1 is a genuine maintenance signal — a semver patch, a public changelog, a compare link, and a container seam that makes Laravel integration slightly cleaner. It does not change the fundamentals: one star, zero dependents, single maintainer, and an unresolved license. Adopt only as a vendored, lockfile-pinned fork with an owned adapter layer and a named exit path to laravel-json-api — or, more prudently, evaluate the maintained Laravel-native alternative first and reserve this package for a time-boxed spike.
How can I help you explore Laravel packages today?