Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backwards-compatible reverse routing #270

Closed
wants to merge 1 commit into from

Conversation

pmjones
Copy link

@pmjones pmjones commented Jan 20, 2024

This PR implements backwards-compatible reverse routing (route generation). It passes all tests on PHP 5.6, but I have been unable to test all the way back to PHP 5.4 or on HHVM.

Existing calls to simpleDispatcher() and cachedDispatcher() continue to work as before, but will not get access to the new RouteGenerator object for reverse routing.

To get access to reverse routing, replace calls to simpleDispatcher()/cachedDispatcher() with calls to the new FastRoute container object to build both the Dispatcher and the RouteGenerator:

use FastRoute\FastRoute;

$fastRoute = new FastRoute(
    function ($r) {
        $r->get(
            '/archive/{username}[/{year}[/{month}[/{day}]]]',
            GetArchiveAction::class
        );
    })
);

N.b.: Pass $options as the second parameter; caching logic via the new FastRoute container is automated and very slightly modified from simpleDispatcher()/cachedDispatcher() logic.

Now you can get the Dispatcher and Route Generator:

// get and use $dispatcher as normal
$dispatcher = $fastRoute->getDispatcher();

// get the route generator
$routeGenerator = $fastRoute->getRouteGenerator();

The RouteGenerator will only work with string handlers; the string handler value doubles as the route name. This means:

  • Closure, object, and array handlers will not work with reverse routing
  • There must be a 1:1 mapping between routes and handlers

To generate a route, pass the string handler and the values to interpolate into the route. The RouteGenerator will build as many optional segments as it can; if an optional value is missing, generation is terminated and the existing URL segments are returned.

$url = $routeGenerator->generate(GetArchiveAction::class, [
    'username' => 'bolivar',
    'year' => '1979',
]);

assert($url === '/archive/bolivar/1979');

If this feature is not within the project scope, or if the implementation fails to meet project design goals, please let me know and I will retract or remedy.

@lcobucci
Copy link
Collaborator

@pmjones thanks for working on this feature.

I'll review it more thoroughly over the week. On a high level, the design diverges a bit from what I had in mind (though I was thinking about v2).

Since we can't guarantee that the route handler points to a class name, I thought on leveraging #269 for providing identifiers.

When it comes to the creation of dispatcher/generator, I was drafting something that moves away from the usage of hash maps to configure the process.

I'm working on documenting and reducing the impact of BC-breaks in v2 and would prefer to focus on its release, instead of having v1.4 in between.

I'll open new prs with my drafts over the next few days and we can discuss things further.

@pmjones
Copy link
Author

pmjones commented Jan 21, 2024

Since we can't guarantee that the route handler points to a class name, I thought on leveraging #269 for providing identifiers.

Understood. I can imagine a string handler being used as the default name; although (depending on the design) an extended class might add that instead.

I'll open new prs with my drafts over the next few days and we can discuss things further.

I look forward to it! (If you find that the time commitment becomes too great, maybe we can revisit this PR for the 1.x series.)

@lcobucci lcobucci mentioned this pull request Jan 30, 2024
5 tasks
@lcobucci
Copy link
Collaborator

@pmjones I'll add on that PR an alternative implementation for the reverse routing (based on extra parameters) - sorry about the delay, last week was a bit crazy... We should be good with v2 pretty soon.

@pmjones
Copy link
Author

pmjones commented Jan 31, 2024

No rush on my part! Looking forward to seeing it.

@pmjones
Copy link
Author

pmjones commented Jan 31, 2024

@lcobucci As a side note, I have incorporated this reverse-routing functionality along with some automated typecasting in CastRoute, as yet unreleased. Let me know if anything there looks like it would be suitable here -- I'd rather have stuff like that in FastRoute proper than in a "decorator" project.

@lcobucci
Copy link
Collaborator

lcobucci commented Feb 6, 2024

@pmjones #277 should give you a general direction.

I believe you'd still be able to use the handlers as names in CastRoute, if you should to 👍

@lcobucci
Copy link
Collaborator

lcobucci commented Mar 4, 2024

#277 merged and I'll release a v2.0.0-beta1 while I update the documentation.

@pmjones thanks for the inspiration, I'll close this in favour of #277.

@lcobucci lcobucci closed this Mar 4, 2024
@lcobucci lcobucci self-assigned this Mar 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants