Slim: Should Slim 4 switch to Symfony 4 Router?

Created on 28 Feb 2018  路  28Comments  路  Source: slimphp/Slim

There are some drawbacks with the current routing functionality provided by Nikic/FastRoute as discussed in #2409. Unfortunately the proposed fix would most likely degrade performance since it has to iterate over every character in the route patterns.

Symfony 4 Router is advertised as being the fastest out there and provides unicode capabilities as of 3.2. It is able to achieve this performance by compiling route patterns and using a regex tree which is much faster than the proposed solution in #2409.

Nikic/FastRoute has said that it would not provide support at the moment for this issue.

In the hypothetical situation that Symfony 4 Router would support all of the route patterns and features in Slim 3 and hopefully a significant performance boost as well as unicode capabilities, would you be in favor of switching for Slim 4?

Slim 4

Most helpful comment

I prefere to keep slim as simple as possible (without having bad design), in my point of view the symfony router is more complex than needed and its not using PSR7

All 28 comments

If the Symfony 4 Router provides additional functionality with an increase in performance, then I'd be in favor.

The downside would any BC changes for those moving from Slim 3 to 4. I see the issue there to be less with defining routes (that happens typically in one place, so can be confidently updated) but more about maintaining the signature of the pathFor helper, whose use is peppered throughout a project.

I took a look at the new Symfony RouteCompiler.php class.

https://github.com/symfony/routing/blob/master/RouteCompiler.php#L95

Now I ask myself: How can this regex/substr/in_array "orgy" be faster then Nikic/FastRoute?

Does anyone know about current performance tests? Symfony 4 Router vs. FastRoute?

We have the project's own claims:

In practice, combining all regular expressions improves URL matching performance by almost two orders of magnitude. In our benchmarks, Symfony 4.1 URL matching is 77 times faster than in previous Symfony versions. This also means that Symfony 4.1 router is now the fastest PHP router, beating FastRoute and all the other routing libraries.

http://symfony.com/blog/new-in-symfony-4-1-fastest-php-router

That also links to a technical explanation of the approach, which includes comparison to FastRoute in particular:

Given the router has the same features and ease of use, I have no objection to moving to another router implementation for Slim 4.

I like how I can swap out the container implementation in Slim 3 to use for example PHP-DI or league/route. Perhaps we can create a router interface and then adaptors can be created for different router implementations?

We have a router interface already available in Slim 3 @llvdl

On another note, please be very careful about benchmarks. There are a lot of people who game benchmarks in order to show bias towards certain projects. The linked article above is a great example.

with /abc{foo}/123-like patterns, the trailing number going from 0 to 399. Matching URL /abc399/399 topped at 154k match/s. (a bit faster than our reference and inspiration, FastRoute, at 65k match/s.)

This is a single end-point style, one of which I would not claim has being standard at all. Without additional pattern information it seems like the author is cherry-picking data to fit the narrative of his story.

It could very well be that Symonfy's new router is good in some certain cases, but it could also be worse in others. Given people choice is a great idea, so 馃憤 for being able to swap the Router implementation for 4.x.

Having said that, I think I would like to stick with FastRoute as a default implementation. We will also need to make sure that the community knows 1 Router is not the same as others when it comes to defining URL Patterns.

I'm confident that Slim won't provide more than one Router. Any alternatives will be provided by third parties.

@akrabat Haha yes, I should have worded that better... but we shall provide interfaces for such things!

At first glance, it sounds great. On the other hand, every router offers different features. There is also no common standard how to define the route paths, placeholders and route conditions. All this would have to be abstracted/mapped by Slim, wouldn't it? In this case, the complexity would shift to slim and thus slow down.

@odan it would simply mean you replace the instance of "RouterInterace" in the container with whatever implementation you want. It wouldn't cause any slowness

It's reasonable to assume that you can't arbitrarily change routers mid-build

@geggleto In this case the interface is just fine. (As long a the route placeholder syntax ({id} vs. [id]) is the same).

@odan the placeholder syntax would not be standardized that would be up to the implementation

Would switching to the Symfony router fix #2165?

I'm in favor of switching routers to Symphony as long as:

  1. The Symphony router must be encapsulated and doesn't bring all of Symphony and the kitchen sink with it.
  2. The performance is the same or better than fastroute. Note: fastroute dispatcher mechanism is strange -- so much so that #2405 was created as a _work-around_ . If Symphony's router performs as well and gives expected and reasonable output then...
  3. As @geggleto pointed out the placeholder syntax should be consistent with how Slim currently operates (or be prepared for lots of griping when 4.x doesn't work "out of the box" like 3.x does).

Why cant we write our own leveraging some of the ideas from Symphony?

@zscally I'm not opposed to your suggestion, but want to avoid _NIH syndrome_. Also, if we were to build our own using R&D (Rob & Duplicate) from Symphony one of the downsides is that what we built would not have as much wide use as a popular Symphony component and therefore would not be as mature or robust.

We can take it as read that we'll use a routing component that's already written.

I prefere to keep slim as simple as possible (without having bad design), in my point of view the symfony router is more complex than needed and its not using PSR7

@akrabat "I'm confident that Slim won't provide more than one Router. Any alternatives will be provided by third parties."
It's ok, but we should implement interfaces for making them interchangeable.

@l0gicgate I am ok with any possible implementation if it will be small and easy to swap, so it depends on the implementation.

I'm also for an interchangable router(interface) with bridges to integrate them (symfony router/fastroute) but definitely not for the symfony router as a default router for slim.

Perhaps some performance metrics (not just speed) but also scalability (i/e resources used - mainly ram) should be investigated?

@akrabat the problem with an opinionated choice to change is that it forces users to change their opinion too. So suggest to do it as @TiMESPLiNTER mentioned

In the hypothetical situation that Symfony 4 Router would support all of the route patterns and features in Slim 3 and hopefully a significant performance boost as well as unicode capabilities, would you be in favor of switching for Slim 4?

Yes. 馃憤馃徎

Sometimes I need some "preprocessing" before the router is getting executed. Why not implement the router/dispatcher as middleware?

Not a hardcore Slim user, so not a real stake in this, but I do think it's important that there are alternatives which don't heavily rely on Symfony components. I haven't researched in depth how many dependencies the Symfony router has, but it looks like it would blow Slim's dependencies quite a bit

@winks the current dependency tracking for Symfony shows that only the requirement of 7.1.3+ is required.

However it does require more symfony packages to bring it up to par with FastRoute.

Namely: symfony/expression-language. The expression-language component required symfony-cache.

We would need this as well I think: symfony/dependency-injection this allows the router to inject route handlers from the DI Container.

So in total 3 additional symfony components are required to use their router in a way that matches FastRoute. This is why I find it highly suspicious that they can claim so much speed. I suspect that when they used their benchmarks they highly-optimized their router without doing the same to FastRoute.

For the record FastRoute can be set to use a cache-file. Once it is using that cache file it is very very fast. We don't have that documented perhaps very well.

From a maintainer stand-point, if the community wants to switch then fine, but I hope we all understand that there are trade-offs. The Router has and always will be a replaceable component, it's just a matter of writing an adapter to the interface... until there's a PSR for a standardized router :)

One of the main reasons we opted for Slim is the reduced number of dependencies: I wouldn't like to see see how this framework starts to grow as others did.
In addition, I still have to see a realistic benchmark that shows that replacing FastRoute really makes a difference.
Please, keep Slim as it is: fast and simple.

@geggleto after looking a little deeper into Symfony's router, it would be a bit of an undertaking to write an adapter for it and as you mentioned a few more dependencies would be required and a base PHP version bump as well from what was currently agreed for Slim 4.

I think the only thing we should do for Slim 4 is ensure we support routes with international characters in them and we're good to go. I did run some benchmarks locally and FastRoute is very fast with 5000+ routes and nested groups I was able to get a response sub 1000ms.

I think we should aim to increase other routers to be dropped in when PSR agrees to a standard.

Closing this. Thanks all for your input.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

boosis picture boosis  路  25Comments

akrabat picture akrabat  路  22Comments

l0gicgate picture l0gicgate  路  27Comments

alexweissman picture alexweissman  路  38Comments

l0gicgate picture l0gicgate  路  83Comments