Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Php Json Api Laravel Package

tenantcloud/php-json-api

A Laravel package for building JSON:API compliant APIs, handling resource serialization, sparse fieldsets, filtering, sorting, pagination, and relationship includes so you can return spec-ready responses with minimal boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with composer require tenantcloud/laravel-json-api and publish the package config (php artisan vendor:publish --tag=...) so you can see the default resource/serializer wiring before you write anything.
  • Look first at the package's resource (serializer) classes and its service provider / route registration — that's where the mapping between your Eloquent models, JSON:API type names, and endpoints lives. Start there rather than at the controllers, because most behaviour is driven by that mapping.
  • Make sure your API routes accept and emit application/vnd.api+json. A quick smoke test is a single GET /api/posts?filter[status]=published&include=author&fields[posts]=title,author — if you get a data array with type/id/attributes/relationships, the plumbing is correct.
  • First real use case: expose one existing model as a read-only resource with one relationship, one filter, and pagination. That exercises the whole stack (document building, sparse fieldsets, includes, query-param validation) in about 30 lines of configuration.

Implementation Patterns

  • One resource class per model, registered by type. Keep attribute whitelisting, relationship definitions, and filter/sort declarations in the resource, not the controller. Controllers should stay thin: resolve the resource, hand the request to it, return the document.
  • Treat the query string as a contract. Filters, sorts, includes, and sparse fieldsets are all untrusted input — validate them against the declared allow-lists and return a JSON:API errors document (400) for unknown filters/sorts rather than silently ignoring them. This is the single biggest source of "why is my API behaving oddly" tickets.
  • Filters are the hot path for customisation. You'll usually write custom filter handlers per resource (exact match, ids, date ranges, comma-separated lists). As of 7.0.2, filter input is normalised in every request bag, so your handler receives the same shape whether the parameters arrived as a query string, a test-built request, or a nested array — write handlers against the normalised value and don't re-parse raw bags yourself.
  • Nested/comma filters are the norm. filter[ids]=1,2,3, filter[published-at][gte]=..., filter[author]=5 — implement these as small dedicated filter classes so they're unit-testable and reusable across resources.
  • Includes and sparse fieldsets belong in the resource. Define relationships once; the package handles include= and fields[type]= on top. If a relationship is expensive, keep it out of the default include set and require an explicit include.
  • Pagination and sorting should be configured per resource (default page size, max page size, allowed sort columns) rather than applied globally in middleware, so each endpoint can tune limits.
  • Error handling: map domain exceptions to JSON:API error objects via the package's exception renderer/handler. Validation failures should produce errors with source.pointer pointing at the offending query parameter, not an HTML 422.
  • Testing pattern: hit endpoints with Accept: application/vnd.api+json, assert on the document structure (assertJsonPath('data.0.type', 'posts')), and add one test per filter handler asserting the SQL/collection result and the error returned for an invalid filter value.

Gotchas and Tips

  • Content negotiation bites first. Missing or wrong Accept/Content-Type yields 406/415 before your code runs. Add the header to your HTTP client's defaults in tests and in the frontend's API client, not per-call.
  • The 7.0.2 fix may change filter input shape. If you previously compensated for filters arriving differently depending on how the request was built (e.g. dot-notation keys vs nested arrays, or filters read from a body bag), remove that workaround and re-run your filter tests. Handlers that inspect $request->query->all()['filter'] directly instead of the normalised parameters are the ones most likely to need attention.
  • IDs are strings in the JSON:API document. Don't === compare a document id against an integer model key; cast deliberately.
  • filter[x]= with an empty value — decide explicitly whether that means "no filter" or "equals empty string". It's a common source of accidental full-table returns.
  • N+1 on includes. Eager-load every relation that can appear in include=; also guard against unbounded includes on large relationship collections by paginating relationship endpoints.
  • Debugging: dump the parsed/normalised parameters object rather than the raw Request when a filter or sort "doesn't work" — most confusion is a naming mismatch (filter[status] vs filter[state]) or an un-declared allowed filter.
  • Extension points to leave yourself: custom filter classes, a base resource for shared attributes/serialisation (timestamps, IDs), and a per-resource meta/links hook — these are the places you'll otherwise end up copy-pasting across a dozen resources.
  • Pin the major version and read the changelog on minor bumps; the package's request-parameter handling has changed behaviour before (7.0.2 itself is a normalisation fix), so treat request parsing as an area to regression-test after upgrades.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource