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

Json Api Symfony Laravel Package

haddowg/json-api-symfony

A Symfony bundle for building JSON:API-compliant APIs, handling resource serialization, relationships, and spec-compliant responses with minimal configuration.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

Build vs. buy for spec-compliant API surface. v1.0.0 represents the moment a hand-rolled JSON:API layer becomes hard to justify: the release consolidates a query engine (filter/sort/pagination incl. cursor keyset on collections, related collections, and pivot/linkage endpoints), adds build-time failure on misconfigured polymorphic/Doctrine-column/pivot types, and closes the spec-compliance gaps (sparse fieldsets, strict query params, related-type factories, host-absolute links). Each of those is a multi-sprint "we'll do it properly later" backlog item for an internal team.

Roadmap: async and non-CRUD workflows are now first-class. The async write seam (202 Accepted / 303 See Other) plus custom (non-CRUD) actions with declared meta-only output means the API layer can now model real product operations — imports, exports, bulk reprocessing, state transitions — without inventing a parallel RPC endpoint style. This directly de-risks any roadmap item that requires long-running or side-effecting operations.

Roadmap: partner/public API and SDK strategy. Bridging resource/operation/relation description overrides into OpenAPI, advertising the id pattern and the Atomic Operations endpoint, and documenting operations as secured-or-public via a security boolean give us a machine-readable contract as a build artifact. That unlocks generated client SDKs, partner sandbox docs, and contract-diff review in CI — a decision that normally needs a separate "API governance" investment. Custom-encoded and policy-sourced resource ids extend this to ID strategy: we can control identifier shape and source without forking serialization.

Authorization and data-exposure decisions. Independent relationship authorization, read-security expressions gating relationship and related endpoints, collection reads gated by a separate securityList key, request-aware visibility/writability predicates, and now write-only attributes (writeable but never serialized out) plus readOnly shorthand mean we can ship nuanced tenancy and field-level access policies declaratively rather than by custom controller surgery. This is the difference between "we can do per-tenant APIs" and "we can do per-tenant APIs without a bespoke audit each time."

API lifecycle and deprecation management. Cache headers and deprecation headers are now part of the framework surface, not bespoke middleware. Combined with strict query parameters and the Validator bridge (including When and date constraints), we get a defensible story for versioning, sunsetting endpoints, and validating writes — all things normally specced as separate platform work.

Integration risk as a decision input. The exception-to-error mapping seam, typed constraint-translator extension, DataProvider SPI base classes, Validator bridge, and the readOnly resource shorthand reduce the coupling between our domain code and the package. That lowers the cost of the eventual upgrade path and is a real factor in the build-vs-buy spreadsheet.

Migration planning. v1.0.0 is a large breaking-change boundary (linkage method renames, lazy-by-default linkage data, opt-in counting and pagination-as-single-source-of-truth, mandatory related-type relationship factory, DataProviderInterface additions, DoctrineExtensionInterface signature change, removed zero-config pivot filter, and belongsToMany pivot writes moving into meta.pivot). This is a discrete, one-time migration project to scope — not an incremental upgrade — and it should be scheduled as such against the 1.0 release rather than discovered mid-sprint.

Platform caveat affecting the decision. Despite being a PHP package, this is a Symfony-oriented implementation (issue tracker and extension naming are Symfony-side). If our target is Laravel, adopting it is a bridging project, not a composer require. That belongs in the build-vs-buy math, and it is the single largest unknown in this evaluation.

When to Consider This Package

Adopt when several of the following hold:

  • We are exposing an API to external consumers or partners, where conformance to the JSON:API spec is a contractual or trust requirement rather than an internal preference.
  • The API surface is relationship-heavy (many-to-many with pivot metadata, polymorphic associations) and we want pivot reads/writes, pivot-prefixed filters, and pivot-aware cursor pagination handled by the framework rather than hand-written.
  • We need a generated OpenAPI contract as a release artifact, for SDKs, partner docs, or contract-diff gating in CI.
  • We want misconfiguration to fail the build (unservable routed types, unprojected sortables, broken polymorphic/pivot declarations) instead of surfacing as a 500 in production.
  • We need API lifecycle primitives — deprecation headers, cache headers, write-only attributes, strict query params — as first-class framework features rather than hand-rolled middleware.
  • Our team is on Symfony, or is愿意 to own a Laravel bridge as a scoped, funded workstream.
  • We can absorb a major-version migration now, in exchange for a stable 1.x line going forward.
  • Authorization needs are non-trivial: per-relationship policy, read-security expressions cascading to related endpoints, request-aware visibility, write-only/read-only attribute semantics.

Look elsewhere when:

  • The API is internal-only, small, and CRUD-shaped — the spec conformance and metadata machinery is pure overhead against a handful of hand-written endpoints.
  • We need first-party Laravel integration (Eloquent-native resources, framework-native auth/policy ergonomics) out of the box; the bridging cost likely exceeds the benefit for a small surface.
  • The organization has standardized on GraphQL, or on a plain REST/OpenAPI-first design where JSON:API's document structure conflicts with existing client expectations.
  • We require an LTS-style support guarantee or a vendor SLA; this is a single-maintainer ecosystem at 1.0.0 with a very large breaking-change delta in the release.
  • No one on the team has JSON:API fluency and there is no appetite to build it — the framework will enforce conventions the team cannot debug.

How to Pitch It (Stakeholders)

To executives: This package is the difference between building an API platform and building an API. v1.0.0 is the stabilization milestone: it closes the spec-compliance gaps, generates our OpenAPI contract automatically, enforces API correctness at build time, and makes async operations and custom actions first-class. It also brings API lifecycle fundamentals — deprecation headers, cache headers, write-only attributes, strict query params — into the framework instead of bespoke middleware. Concretely, it converts several recurring roadmap asks — partner API access, generated SDKs, long-running operations, tenant-scoped field visibility, and endpoint sunsetting — from bespoke projects into configuration. The cost is a one-time migration from any pre-1.0 usage, plus an integration assessment if we are standardizing on Laravel rather than Symfony. Recommendation: fund a short spike to quantify the Laravel bridging cost, then decide; treat the 1.0 migration as a scheduled workstream, not incidental maintenance.

To engineering: v1.0.0 is a breaking-change boundary and should be treated as a discrete migration with its own ticket and test plan. The high-impact items: relationship linkage methods renamed to data; linkage data is lazy by default; counting and pagination are now opt-in with pagination as the single source of truth; the related-type relationship factory is mandatory; DataProviderInterface gains relatedToOneMatches() / relatedToOneMatchesBatch(); DoctrineExtensionInterface::apply() now takes an ExtensionContext; the zero-config filter[position] pivot filter is removed in favor of a pivot.-prefixed declaration; belongsToMany pivot writes now read from meta.pivot (symmetric with reads) and pivot meta is rendered on primary-resource linkage; unknown sparse-fieldset members are rejected under the strict gate; read-security now cascades to relationship and related endpoints, so existing authorization tests will need review. Upside for us: build-time validation of polymorphic/pivot/column misconfiguration, an exception-to-error mapping seam, DataProvider SPI base classes, cursor pagination on related and pivot endpoints, an async write seam (202/303), custom (non-CRUD) actions with declared meta-only output, the Atomic Operations extension, and a completed Validator bridge (When, date constraints). Please produce a diff-level migration estimate against our current usage before we commit a release date.

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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin