tobscure/json-api-server
A PHP library for building JSON API-compliant APIs, providing serializers, resource transformers, and relationship handling. Framework-agnostic and easy to integrate into Laravel or any PHP project.
202 Accepted / 303 See Other), resource and relationship links, and richer type schemas (Obj, Any, AnyOf, AllOf, OneOf, Not, plus nullable() on sub-types). That means "adopt JSON:API" becomes a defensible decision rather than a compromise, because you no longer need custom glue for the edge cases clients will eventually ask for.ApiResponse classes — is a multi-sprint investment that will drift from the spec over time.Id::writableOnCreate() — unblocks offline-first / optimistic mobile flows and idempotent retries.202 with a status resource instead of timing out.Page::$rangeTruncated — enables infinite-scroll feeds and stable pagination over large, changing datasets.Context::profileRequested() / activateProfile()) — lets you ship opt-in extensions without forking the API version, a cheaper path than /v2 for additive changes.JsonApi::errors() overrides give you a consistent, client-parseable error shape and a single place to tune detail messaging (including :key substitutions for localization). Fewer "why did the API return this?" tickets.Resource::id(), ErrorProvider singularization, trait rename, removed json_api_response() and Context::queryParam(), moved Extension\Atomic). The product decision here is a governance one: pin exact versions, and if any code was written against earlier RCs, budget a migration ticket before the GA cut.Good fit when:
include, sparse fieldsets, and relationship endpoints without inventing conventions.Look elsewhere when:
related vs. relationships endpoints) impose a real learning curve that will show up in estimates.For executives: We're standardizing our API on JSON:API using a mature Laravel package rather than building the conventions ourselves. That gets us spec-compliant behavior, machine-generated OpenAPI documentation, and standard error responses out of the box — which reduces integration time for partners and mobile clients, and removes a recurring source of support tickets. It also unlocks capabilities we'd otherwise build: client-generated IDs for offline-first mobile, async responses for long-running jobs, and cursor pagination for large datasets. The caveat is timing: the current release is a release candidate with breaking changes, so we pin the version, treat upgrades as planned tickets, and target GA before we commit any external partner to the contract.
For engineering: The package now covers query-parameter validation, OpenAPI schema generation, resource/relationship links, and JSON:API profiles, with extension hooks (Endpoint::headers(), response(), schema(), Create::saved(), Update::saved()) so we don't fork it for bespoke behavior. The RC changes several public APIs — Resource::id() returning an Id field, singular ErrorProvider::getJsonApiError(), the JsonApiError trait rename, and removed helpers (json_api_response(), Context::queryParam()) — so plan a short migration pass and avoid building against removed surfaces.
How can I help you explore Laravel packages today?