sycho/json-api
A Laravel/PHP package for building JSON:API-compliant APIs. It helps serialize resources, handle relationships and includes, and return standardized responses, making it easier to expose clean, spec-compliant endpoints with less boilerplate.
Architecture fit. sycho/json-api is a serialization-layer library, not an application framework. It implements the JSON:API 1.0 specification (documents, relationships, compound documents, sparse fieldsets, pagination links, errors) by separating the encoder/decoder from schema definitions that you author per resource type. That maps cleanly onto a Laravel application's HTTP boundary: Eloquent models stay untouched, controllers return encoder-built responses, and schema classes act as a typed contract between persistence and wire format. It does not provide routing, controllers, validation, persistence, authorization, or query parsing — every one of those is glue we own. The package is framework-agnostic (PSR-friendly), so Laravel integration is a thin service provider plus response middleware, not a deep coupling.
Integration feasibility. Composer-installable, MIT-licensed, no native extensions. The realistic work is: (1) register a container binding for the encoder with config, (2) author one schema class per exposed resource (this is the bulk of the effort and is proportional to API surface, not to the package), (3) write a response builder that satisfies Laravel's Responsable/JsonResponse contract, (4) add middleware for content negotiation and error rendering. For a team already fluent in PHP/Laravel, this is a small spike (days, not weeks) for a read-only endpoint and a straightforward extension to writes via the decoder. The library is a fork of the well-established neomerx/json-api; the API surface is therefore familiar to anyone who has used the parent, which materially lowers discovery cost.
Technical risk. This is where the package fails hard on standard adoption signals:
| Signal | Value | Implication |
|---|---|---|
| Stars | 1 | Effectively no community validation |
| Dependents | 0 | No production usage we can observe |
| Last release | 2023-04-16 | ~2+ years stale; PHP/Laravel version drift is likely |
| Maintainers | 1 (apparent) | Bus factor 1, no succession path |
| Score | 0.135 | Composite quality signal is very low |
| Opportunity | 54.29 | Latent demand for JSON:API in PHP, not evidence for this package |
The opportunity score is notable: it is the one metric that is not depressed. Read correctly, it says "JSON:API as a spec has pull in the PHP ecosystem," not "this fork is the right vehicle." The dominant risks are (a) fork divergence — the delta from upstream neomerx/json-api is unknown from the metadata and must be reviewed in the diff, (b) compatibility ceiling — a 2023 release may not declare PHP 8.3/8.4 or Laravel 11/12 support in composer.json, forcing constraint overrides, and (c) silent spec drift — a low-traffic fork may lag spec clarifications and never publish a changelog.
Key questions to resolve before approval.
neomerx/json-api? Is SychO9's fork a thin patch, a rename, or a divergent rewrite? If thin, we should depend on upstream and cherry-pick.composer.json declare PHP ^8.1+ and does the test matrix exercise the Laravel versions we run?application/vnd.api+json?Stack fit. Good on paper: PHP 8.x, Composer, no framework lock-in, PSR-compatible. It slots underneath Laravel's response pipeline with a service provider and a response macro, and alongside existing middleware (auth, throttling, ETag). It composes with — rather than replaces — Eloquent, Form Requests, and Policies. The one architectural friction point is that Laravel's idiomatic serialization is JsonResource/ResourceCollection; introducing a second serialization idiom alongside it creates a "two ways to do it" problem that must be resolved by policy, not by tooling.
Migration path. Adopt as a greenfield-only serialization layer behind an internal abstraction we own — call it ApiDocumentBuilder — with the third-party encoder as an implementation detail. This is the critical decision: never let schema classes or encoder calls leak into controllers. Concretely:
JsonApiEncoderAdapter (this package) and EloquentResourceAdapter (native fallback).Compatibility. Gate the spike on a hard compatibility checklist: PHP version in require, minimum PHPUnit, PSR-4 autoload sanity, no abandoned transitive dependencies, and a clean composer why-not against our pinned Laravel. If composer.json is permissive (e.g., php: >=7.4 with no upper bound), treat that as untested, not compatible, and plan to own the test matrix ourselves.
Sequencing. (1) Upstream-vs-fork diff review and license/lineage confirmation — one engineer-day. (2) Compatibility spike against our exact PHP/Laravel pair — two to three days. (3) Single-endpoint vertical slice with contract tests — one sprint. (4) Schema conventions doc and a reusable base schema class — half sprint. (5) Expand coverage endpoint by endpoint; no big-bang. Total realistic time-to-first-value for a two-engineer team: two to three weeks. Full API surface scales linearly.
Maintenance. The package is effectively unmaintained by ecosystem standards: one star, zero dependents, no release in over two years. Plan for us to be the de facto maintainer of our copy. That means vendoring or forking into our monorepo at adoption time, not a floating ^1.0 constraint — we need the ability to patch PHP compatibility ourselves without waiting on an upstream that may not respond. Budget roughly 5–10% of one engineer per quarter for dependency hygiene on this component alone.
Support. There is no vendor, no SLA, no support channel of consequence, and no observable community to ask questions of. Documentation is inherited from neomerx/json-api at best. Onboarding material must be written in-house. This is acceptable for a stable, narrow serialization library and unacceptable for anything touching auth, crypto, or I/O — and it is narrow, which is the mitigating factor.
Scaling. JSON:API's compound documents and include parameters concentrate cost at serialization time and create classic N+1 hazards: relationship resolution must be batched via eager loading, and schema objects should be cached per request or per worker. Encoder throughput is generally fine; the risk is payload size — sparse fieldsets are a spec feature precisely because default responses are large. We must enforce fieldset and include allow-lists per endpoint or we will ship 10x payloads under load. Benchmark one endpoint with realistic includes before any capacity commitment.
Failure modes. The realistic ones, in rough order of likelihood: (1) Composer breakage on a PHP or Laravel minor upgrade, blocking the whole build because the constraint is stale; (2) silent contract drift — incorrect links, meta, or relationship linkage that passes an HTTP 200 smoke test and fails a strict consumer; (3) partial-spec implementation surfacing only when a client uses sparse fieldsets or sorting; (4) fork abandonment, which is less an event than a slow default and is mitigated entirely by forking at adoption; (5) two-idiom confusion, where new engineers serialize with API Resources while the JSON:API path silently diverges.
Ramp-up. Two distinct costs. Tooling ramp-up is short — a competent Laravel engineer is productive with the encoder in a day. Spec ramp-up is the real cost: JSON:API has non-obvious semantics (resource linkage, included deduplication, error object structure, self/related link rules) that engineers systematically get wrong on first contact. Budget a half-day spec workshop and a written conventions document before the second endpoint, or expect inconsistent output across teams.
Recommendation. Approve a time-boxed spike only, conditional on the fork-vs-upstream diff review and a green compatibility matrix against our exact PHP/Laravel pair. Do not adopt as a strategic dependency without also committing to vendor the source and own the test matrix. If the business requirement is "a well-shaped API" rather than "JSON:API compliance," redirect to Laravel's native API Resources and revisit this package only when a consuming client contractually requires the spec.
How can I help you explore Laravel packages today?