gointegro/hateoas-bundle
GoIntegro Hateoas Bundle brings HATEOAS to Symfony REST APIs: a JSON:API-style response format with pagination, sorting, filtering, sparse fieldsets, and embedded related resources, plus annotations and helpers to expose resources and links with minimal configuration.
Architecture fit — the headline risk: this is not a Laravel package. Despite being catalogued under a "Laravel/PHP" search, gointegro/hateoas-bundle is a Symfony bundle. Its integration surfaces assume a Symfony Kernel, HTTP kernel event listeners, a service container with compiler passes, Doctrine annotations/attributes for resource metadata, and Doctrine ORM entities as the resource model. Laravel supplies none of these: no bundle registration, no compiler passes, Eloquent instead of Doctrine, and a different routing/serialization layer. The reusable portion is the underlying gointegro/hateoas core plus the metadata/serialization concepts; the Symfony glue is not portable and would need to be re-implemented as Laravel service providers, middleware, and an Eloquent-backed metadata driver.
Integration feasibility. In a Symfony + Doctrine shop, feasibility is high — this is exactly the shape of codebase the package was built for, and it delivers real value: HAL/HATEOAS serialization, relation embedding, sparse fieldsets, pagination, and inclusion of related resources without hand-writing serializers per endpoint. In a Laravel/Eloquent shop, feasibility is low-to-medium: you would be porting a metadata-driven serializer onto a repository/pagination model it was not designed against, with the bundle's most valuable parts (Doctrine association traversal, entity metadata caching) needing replacement. Realistic effort is a multi-week spike plus ongoing ownership, not an afternoon composer require.
Technical risk.
doctrine/annotations wind-down). This is a known future break, not a hypothetical.Key questions. Is our target stack Symfony/Doctrine or Laravel/Eloquent? Which Symfony/Doctrine/PHP majors does the latest tag actually support (verify against composer.json, not the README)? Does the core library function without the bundle, and how much glue is truly framework-coupled? Who owns the fork when a CVE or a PHP minor lands?
Stack fit. Green-field Symfony 5/6 + Doctrine ORM: proceed, with a fork pinned to a known commit. Laravel/Eloquent: do not adopt the bundle — mine it for design (HAL link structure, embedding semantics, fieldset negotiation) and implement against Laravel primitives.
Migration path.
nocarrier/hal or a small custom transformer) plus an allow-listed sparse-fieldset/include parser as middleware, backed by API Resources and whenLoaded. This is typically smaller and safer than porting Doctrine metadata.Compatibility. Produce a verified matrix before committing, not a README-derived one: PHP version, Symfony major, Doctrine ORM major, doctrine/annotations presence, and PSR/symfony/serializer versions. Add a canary test suite that fails loudly on the next dependency bump — this is the only reliable signal that the fork is drifting.
Sequencing. Spike (1 week): stand up one read-only GET resource with one relation and one fieldset. Gate: does the payload satisfy the contract without custom serializers? Pilot (2–3 weeks): 3–5 read endpoints, pagination, error shape, cache warmup in the deploy pipeline. Expand only after the pilot proves payload correctness and query counts. Avoid writes/POST-PATCH until the read path is boring.
Alternatives to weigh. For Laravel, spatie/laravel-query-builder + API Resources covers filtering/fieldsets/include with far better maintenance; HAL is then a thin formatting concern. willdurand/hateoas is the other PHP HATEOAS option but carries similar staleness questions. The honest "build" here is small.
Maintenance. Assume fork ownership in perpetuity. Budget for: dependency-matrix bumps each Symfony/PHP cycle, annotation→attribute migration, and a security review cadence on client-controlled projection logic. That is a recurring line item a TPM must fund, not a one-time integration cost.
Support. No vendor, no SLA, minimal issue throughput at this adoption level. Internal documentation and a named owner are mandatory; otherwise the fork becomes tribal knowledge and the upgrade tax compounds silently.
Scaling. Principal concern is query amplification: relation inclusion and embedding are exactly the patterns that produce N+1 unless eager-loading is enforced. Require eager-load assertions in tests and query-count budgets per endpoint. Serialized payloads cache well — put a shared cache in front of hot resources and reuse the metadata cache pool across workers (cold metadata caches on every deploy are a common, ugly failure). Pagination defaults must be capped server-side; a client-controlled page[size] is a DoS lever.
Failure modes.
Ramp-up. Steep for a Laravel-native team (Doctrine entity lifecycle, association mapping, Symfony DI semantics, annotation metadata). Plan on 2–3 weeks before a developer is productive, and designate one engineer as the fork owner. For a Symfony/Doctrine team, ramp-up collapses to days — which is the whole decision: the package's value is inversely proportional to how far your stack is from Symfony + Doctrine. Given zero dependents and a 4.28 score with no production evidence, default to a small internal HAL layer unless the stack is already Symfony/Doctrine and the read-only spike clears.
How can I help you explore Laravel packages today?