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

Link Util Laravel Package

fig/link-util

A small PSR-13 implementation for PHP: interfaces and classes for representing links (URI, rel, attributes) and link providers, plus serializers for HTTP Link headers and HAL-style JSON. Integrates with PSR-7 without extra dependencies.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

What it is. fig/link-util is the PHP-FIG reference implementation of the PSR-13 hypermedia link contracts: Link, EvolvableLink, LinkProvider, and EvolvableLinkProvider. It is roughly four small value-object classes with no I/O, no state, no configuration, and a single dependency on psr/link. Functionally it converts a URI + rel + attributes into an object graph and back — nothing more.

Architecture fit. This only earns a place in the stack if we are actually speaking PSR-13. Laravel does not: routing, URL generation, and Illuminate\Http\Response have no notion of link providers, and Laravel's HTTP layer is built on Symfony's HttpFoundation, not PSR-7/PSR-13. Adopting this package therefore means adopting a specification our framework doesn't natively produce or consume. The legitimate use cases are narrow and concrete: emitting Link: headers (RFC 8288), building a HATEOAS/HAL/JSON:API layer on top of JsonResource, or exposing pagination relations (next/prev/first/last) through a stable contract. If none of those is a funded requirement, this is a dependency we take on for architectural symmetry we don't get value from.

Integration feasibility. Composer-only. No service provider, no config publish, no facade, no migrations. PSR-4 autoload, MIT licensed, and the interfaces (psr/link) are widely understood. The real integration work is not the package — it's the serialization to and from the wire format, which fig/link-util deliberately does not provide. We would write that ourselves.

Technical risk. Functional risk is very low; ecosystem risk is not zero. The package has been frozen since a single 2016 release, and it constrains psr/link to the 1.x line. Anything in the dependency graph that later requires psr/link ^2 (which added typed signatures) will either block that upgrade or fail at class-load with a signature mismatch. This is a "cheap now, mildly annoying in three years" dependency. A secondary risk is conceptual rather than technical: the Evolvable* classes are immutable, withHref() returns a clone, and developers who mutate-and-discard will silently lose their change.

Key questions.

  • Who is the consumer — internal code, or external API clients parsing Link headers? If internal only, a two-class DTO is cheaper.
  • Does anything in our Composer graph need psr/link ^2, now or on a known roadmap?
  • Would symfony/web-link be a better fit, given it provides the same PSR-13 implementations plus HttpFoundation header integration and preload helpers, with active maintenance?
  • The metadata is internally inconsistent — 1,816 stars and a 9.45 score against 0 known dependents and an opportunity score of 28.07. The score almost certainly reflects static code quality and stability, not ecosystem pull. We should weight "frozen since 2016" and "zero dependents" over the star count.

Integration Approach

Stack fit. Laravel 9–11 on PHP 8.1+ runs this without modification; the classes are simple enough to be free of deprecation noise. Install is composer require fig/link-util. The natural seams are a JsonResource subclass, a response macro, or a small middleware that appends a Link header, all fed by a domain service that decides which relations a resource has.

Migration path. Contract-first. Depend on psr/link interfaces in our own code and type-hint LinkProviderInterface; bind EvolvableLinkProvider in a service provider as the concrete implementation. That keeps the swap surface to a single binding. If we later move to symfony/web-link or an in-house implementation, it is a one-line container change rather than a refactor. Given the package is four classes, the honest baseline option is to skip it entirely and write our own implementation behind the same interfaces — MIT permits either path, and the exit cost is near zero in both directions.

Compatibility. Confirm resolver behavior against the rest of the graph, particularly symfony/*, before committing. Expect the lockfile to pin psr/link to 1.x as a consequence. Validate on the oldest PHP version we support, not just the CI default.

Sequencing.

  1. Identify and document one concrete consumer (Link headers or a HAL-style payload).
  2. Add psr/link interface-only contracts to the domain layer.
  3. Bind the FIG implementation behind a factory.
  4. Write the serializer (header and/or body) with tests covering URI encoding, duplicate rel values, and relative-vs-absolute hrefs.
  5. Only then expose links in a public API version.

Operational Impact

Maintenance. Effectively zero code maintenance and a permanently carried version constraint. Treat the package as vendored code: it will not receive fixes, so any bug we find is ours to patch via fork. An ADR recording the choice, the pinned constraint, and the exit plan is the main operational artifact.

Support. No vendor. Support is PHP-FIG community and, realistically, ourselves. Acceptable only because the code surface is small enough to audit in an afternoon.

Scaling. Irrelevant to throughput — in-memory value objects with no I/O, no caching, no globals. The scaling concern is payload-shaped: link count per response grows header size, and some proxies cap Link headers around 8KB, so a resource with dozens of relations is better served by body-embedded _links than by headers.

Failure modes.

  • Signature mismatch on a future psr/link 2.x resolution — fatal at class load, caught in CI if we test the lockfile.
  • Immutability misuse: discarding the clone returned by withHref() silently drops the link.
  • Duplicate or conflicting rel values across layers producing ambiguous semantics for clients.
  • Header injection if href is built from unvalidated user input; URIs must be validated and encoded before serialization.
  • Cache-key drift when links are computed per-request but the response is cached upstream.

Ramp-up. Under an hour for a mid-level engineer, and most of that is learning PSR-13 semantics rather than the library. The immutability contract should be stated explicitly in the ADR so it isn't rediscovered in production.

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager