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

Url Resolver Laravel Package

innmind/url-resolver

Lightweight PHP library that maps incoming URLs to the resources that handle them. Register resolvers to match request paths, extract parameters, and return controllers or handlers, keeping routing logic decoupled, testable, and framework-agnostic.

View on GitHub
Deep Wiki
Context7

Getting Started

innmind/url-resolver is a small, framework-agnostic abstraction whose job is to turn a URL into something usable — either an absolute URL (resolving a relative reference against a base) or the handler/callable responsible for it, depending on which part of the release notes you read. Before you do anything, reconcile those two readings against the actual resolver interface you install; the package's own descriptions conflict, and this package has no Laravel documentation, no dependents, and is archived, so you are on your own for discovery.

Minimal steps:

composer require innmind/url-resolver:^5.1 --with-all-dependencies

Then confirm constraints before writing code:

composer show innmind/url-resolver
composer why-not innmind/immutable 5   # diagnose resolution failures

What to check first, in order:

  1. vendor/innmind/url-resolver/src/ — read the resolver interface and every concrete implementation. This is your real documentation. At v5.1.0 the public surface is tiny, so a 10-minute read covers it.
  2. composer.json — confirm you are on PHP 8.2+ (8.1 was dropped in 5.1.0) and that innmind/immutable resolves to ^5. If your app still pins immutable ^4, you cannot install this at all.
  3. Whether innmind/immutable types appear in the public signatures. If they do, expect Maybe/Seq-style values at every call site — a real ramp-up cost for a Laravel team.

First practical use case: canonical absolute URLs for outgoing requests and responses. Given a base URL from config('app.url') and a relative path/redirect target, resolve it to an absolute URL in one place instead of repeating url(), URL::to(), and hand-rolled sprintf('%s/%s') logic across controllers. Wire it once:

// app/Providers/AppServiceProvider.php (register)
$this->app->singleton(Resolver::class, fn () => new Resolver(new BaseUrl(config('app.url'))));

Then resolve at the boundary:

// app/Http/Controllers/RedirectController.php
public function __invoke(Request $request, Resolver $resolver)
{
    return redirect()->away((string) $resolver->resolve($request->query('next')));
}

That is a day-to-day win: one audited implementation of relative → absolute resolution, testable without booting Laravel.

Implementation Patterns

  • Bind, don't instantiate. Register the resolver as a singleton in a service provider and inject the interface. This keeps the package swappable if you later outgrow an archived dependency — you can write a 40-line Leagues\UrlResolver implementation behind the same contract.

  • Resolve at the edge. Do URL resolution in a middleware, form request, or the first line of a controller action; never mid-domain. Domain services should receive absolute URLs as plain strings, not resolver instances.

  • Middleware for redirect/return URL whitelisting. A small middleware that resolves ?redirect= / ?return= parameters and rejects anything that resolves to a foreign host is the highest-value integration. Validate the resolved absolute host against config('app.url'), not the raw input:

    $absolute = (string) $resolver->resolve($request->query('return', '/'));
    abort_unless(parse_url($absolute, PHP_URL_HOST) === parse_url(config('app.url'), PHP_URL_HOST), 400);
    
  • Outgoing HTTP clients. When calling an internal service with a relative path, resolve against that service's base URL from config, then Http::get($absolute). Keeps a single source of truth for each service base.

  • Sitemap / feed / notification generation. These are the classic places where every link must be absolute. Resolve once in a builder class and hand arrays of plain strings to the template or mailable — this also dodges queue serialization problems.

  • Console and jobs. The package is framework-agnostic, so it works identically in a queued job or Artisan command. Resolve in the job, ship only strings across the queue boundary.

  • Testing. Test your resolver wiring with absolute fixtures, asserting on the returned string or handler — not on internal object state. Because resolution is pure, these tests need no database and no HTTP fake:

    it('resolves relative paths against the base', function () {
        $resolver = new Resolver(new BaseUrl('https://example.com/app/'));
        expect((string) $resolver->resolve('../foo?x=1'))->toBe('https://example.com/foo?x=1');
    });
    
  • If you also use the handler side. For non-Laravel entry points (webhooks, a legacy front controller, a queue consumer picking a handler from a URL), the URL → handler mapping is a clean way to keep dispatch out of routes/web.php. For standard HTTP routing inside Laravel, use Laravel's router; don't build a parallel routing table.

Gotchas and Tips

  • The package is archived. Two stars, zero dependents, no releases since September 2023. Treat it as vendored code you happen to install: read the source, pin it exactly (5.1.0), and have a replacement plan. Do not make it load-bearing for routing.
  • The documentation contradicts itself. Release notes and the short description frame it as URL → handler resolution; the package title frames it as relative → absolute resolution. Verify which behavior the interface you installed actually provides before designing around it. This is the single biggest time-sink risk.
  • 5.1.0 is a breaking change wearing a minor version. It drops PHP 8.1 and requires innmind/immutable v5. Under a ^5.0 constraint, a routine composer update silently pulls it in. Pin exactly and review lockfile diffs.
  • innmind/immutable v5 conflicts are the most likely install failure. The error reads like a package bug; it is usually a second dependency pinning ^4. Run composer why-not innmind/immutable 5 rather than guessing.
  • Laravel 10 apps on PHP 8.1 are locked out. Either stay on the previous line or upgrade PHP first — and do it in a separate PR so a resolution failure has an unambiguous cause.
  • Relative URL edge cases are where these libraries earn their keep, and where hand-rolled code fails. Explicitly test: protocol-relative (//host/path), root-relative (/path), dot segments (../, ./), query-only (?page=2), fragment-only (#top), empty string, and a base URL that lacks a trailing slash. Also test a base with a path (https://example.com/app/) — the difference between https://example.com/app/foo and https://example.com/foo is the bug you will ship.
  • Never serialize the resolver's return objects. JSON responses, Blade, logs, and queue payloads should receive strings or arrays. Cast to string or map to arrays at the boundary.
  • Debug by casting, not dumping. dump((string) $resolved) and dump($resolved->toArray()) are readable; the object graph is not.
  • Watch for innmind/immutable types leaking into your app. If the resolver returns Maybe/Either-style values, every consumer needs functional idioms that most Laravel developers don't use daily. Wrap the resolver in your own thin adapter that returns ?string or throws, and keep the monads inside app/Support/.
  • Open-redirect risk. Resolution alone does not make a user-supplied URL safe. Always compare the resolved host against an allowlist; resolving //evil.com produces https://evil.com.
  • Extension points are minimal by design. The way to extend this is to implement the resolver interface yourself, not to subclass. That is also your exit strategy if the archived package rots — keep a single binding in AppServiceProvider so swapping the implementation is a one-line change.
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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
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