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

Object Routing Bundle Laravel Package

webfactory/object-routing-bundle

Symfony bundle for object-oriented routing: map request parameters to domain objects and generate URLs directly from objects via configurable route providers, keeping controllers thin and URL logic reusable.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with Composer: composer require webfactory/object-routing-bundle. If you are not using Symfony Flex, register the bundle class from the package README in config/bundles.php.
  • Look first at the bundle’s README.md, DependencyInjection/Configuration.php, and Resources/config/services.*. This bundle is thin; most behavior lives in the underlying webfactory/object-routing library. Read that package’s README and its router/mapper classes before writing integration code.
  • Minimal first use case: stop hard-coding route names for one entity. Define a normal Symfony route (post_show with {id}), map App\Entity\Post to that route, then generate links from the object itself.
// src/Entity/Post.php
// Exact attribute/annotation name depends on the bundle version; confirm in the source.
#[ObjectRoute('post_show', ['id' => 'id'])]
class Post { ... }
// Controller: inject the object-aware router service, not necessarily Symfony's RouterInterface.
use Webfactory\ObjectRouting\ObjectRouterInterface; // check exact FQCN

public function show(Post $post, ObjectRouterInterface $objectRouter): Response
{
    $url = $objectRouter->generate($post); // /posts/42
    // ...
}
{# Exact helper name may differ; check the bundle's Twig extension. #}
<a href="{{ object_path(post) }}">{{ post.title }}</a>
  • If you are coming from Laravel, think of this as a way to avoid repeating route('posts.show', $post) and instead derive the route from the object itself. The win is largest when many templates and controllers link to the same domain objects.

Implementation Patterns

  • Put mapping next to the domain object when you own the class. Attributes/annotations keep the route name and parameter mapping discoverable. Use YAML/config mapping only for vendor classes you cannot modify.
  • Wrap the package in one app service. Create App\Routing\ObjectUrlGenerator that injects the bundle’s router and exposes generate(object $object, array $parameters = []): string. This keeps the rest of your codebase independent of the bundle’s API and makes it trivial to mock or replace later.
  • Use it for mixed-type link lists. A feed containing Post, User, and Product objects becomes simple: iterate and call $objectUrlGenerator->generate($item). This is the clearest day-to-day use case.
  • Pass extra parameters explicitly. Keep the object mapping to the minimum required params (id), and pass locale, page, or tracking params at call time if the router supports a parameters argument:
$url = $objectUrlGenerator->generate($post, ['page' => 2]);
  • Use absolute URLs for emails/notifications. If the object router exposes Symfony’s reference type, use it; otherwise wrap Symfony’s UrlGeneratorInterface with the generated path.
  • Test the mapping, not the framework. Add a kernel test that boots the container, fetches the object router, and asserts generate($post) returns /posts/42. Add one assertion per mapped class. This catches missing mappings before a template does.
  • Migrate incrementally. Start with one high-traffic entity and its Twig templates. Keep old path('post_show', {id: post.id}) calls until the object route is proven. Avoid a big-bang migration across the whole app.
  • Use a fallback for unmapped objects. If your app has many optional linkable objects, catch the package’s “no route for object” exception in your wrapper and log a warning or fall back to #. Do not let a missing mapping break a whole page.

Gotchas and Tips

  • Do not assume $router->generate($post) works. Symfony’s RouterInterface::generate() is typed to accept a string route name. This bundle may decorate the router, but it may instead expose a separate object router service or Twig function. Check the service definition and Twig extension before choosing the call site.
  • Attributes vs annotations. Older versions of this fork used Doctrine annotations; newer Symfony/PHP versions use attributes. Confirm which class exists (Attribute/ObjectRoute.php vs Annotation/ObjectRoute.php) and that your annotation reader is configured if you are on annotations.
  • Mapping failures are runtime failures. A missing mapping usually throws when a URL is generated, not when the container compiles. Add a CI test that iterates over every mapped class and calls the generator. This is the single highest-value safeguard for this package.
  • Parameter mapping is property-path based. The array values must resolve to real getters/properties, and route placeholders must match keys exactly. Null or object values often produce broken URLs; map only scalars.
  • Clear cache after mapping changes. Attribute/annotation metadata is cached. If a new mapping does not appear, run bin/console cache:clear and check the annotation reader cache in dev.
  • Twig helper name matters. The bundle may provide object_path, object_url, or override path. If you override path, test every template that uses it; a global override can surprise other bundles.
  • Performance: annotation/attribute scanning can be slower than a compiled route map. If you generate thousands of object URLs per request, cache the resolved mapping in your own service or use a compiler pass.
  • Low adoption means you own the edge cases. With 0 stars and few dependents, expect sparse docs. Pin the version in composer.json, read the source, and keep the wrapper service so you can replace it with ~50 lines of custom code if the bundle falls behind.
  • Extension point: decorate the core route mapper/resolver (check webfactory/object-routing for the interface) if you need dynamic mappings, e.g., from a database or for third-party classes. Symfony service decoration is usually cleaner than forking.
  • Authorization is still your job. Object routing only builds URLs. It does not check whether the current user can view the object. Keep your voters/access checks in the controller or Twig before rendering the link.
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.
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
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect