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

Support for adding routes dynamically #62

Closed
toverux opened this issue Jul 15, 2015 · 3 comments
Closed

Support for adding routes dynamically #62

toverux opened this issue Jul 15, 2015 · 3 comments

Comments

@toverux
Copy link

toverux commented Jul 15, 2015

Hello,

The lib lacks support for adding rçoutes dynamically. With Express for example, we can add a route at any moment by doing app.get('/my/route', callback). Reading the source code, I see that FastRoute isn't written in a way that let us easily add routes after the initial "mass import" and "mass parsing". So, if I want to add routes when the app is running, I have to recreate from zero a new dispatcher and destruct the old.

I know that this library isn't you main hobby, but do you think you could, in the future, add support for adding routes in an expressy-way?

Anyway, thanks for your work on this routing library, that's exactly what I needed (simple and fast).

@nikic
Copy link
Owner

nikic commented Jul 18, 2015

Given the way this library works, I don't think there would be much benefit from trying to incrementally modify an existing dispatcher (over just completely regenerating it, that is).

Here's how I'd go about implementing the automatic regeneration of the dispatcher right now (not tested):

class IncrementalDispatcher extends RouteCollector implements Dispatcher {
    private $dispatcher;
    private $dispatcherFactory;

    public function __construct(
        RouteParser $parser, DataGenerator $generator, callable $dispatcherFactory
    ) {
        parent::__construct($parser, $generator);
        $this->dispatcherFactory = $dispatcherFactory;
    }

    public function addRoute($httpMethod, $route, $handler) {
        parent::addRoute($httpMethod, $route, $handler);
        $this->dispatcher = null;
    }

    public function dispatch($httpMethod, $uri) {
        if (null === $this->dispatcher) {
            $this->dispatcher = call_user_func($this->dispatcherFactory, $this->getData());
        }
        return $this->dispatcher->dispatch($httpMethod, $uri);
    }
}

// Usage:
$dispatcher = new IncrementalDispatcher(
    new RouteParser\Std, new DataGenerator\GroupCountBased, function($data) {
        return new Dispatcher\GroupCountBased($data);
    }
);

$dispatcher->addRoute(...);
$dispatcher->addRoute(...);
$dispatcher->dispatch(...); // Dispatcher regenerated here
$dispatcher->addRoute(...);
$dispatcher->addRoute(...);
$dispatcher->dispatch(...); // Dispatcher regenerated here

For the runtime addition of routes the caching doesn't make much sense, so this combined the RouteCollector and Dispatcher into one, invalidating the dispatcher object whenever a new route is added.

@toverux
Copy link
Author

toverux commented Jul 24, 2015

Yes, this is an acceptable solution for now. Thanks for the IncrementalDispatcher, I will use it.
Feel free to close this issue or not, in the case you're thinking about changing the lib's architecture in the future.

@nikic nikic closed this as completed Aug 20, 2015
@huanghantao
Copy link

How do I replace handler dynamic? I found fastroute can't overwrite route, but I just want to replace hander.

for example:

$dispatcher->addRoute('POST', '/prefix/{other:.*}', new Handler(['middleware' => ['BarMiddleware']]));

I want to replace to new new Handler(['middleware' => ['FooMiddleware']]).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants