Routing PSR

576 views
Skip to first unread message

Damiano Petrungaro

unread,
Nov 17, 2016, 4:12:16 PM11/17/16
to PHP Framework Interoperability Group
Hi everyone.

I'm doing a microframework (for educational purposes), with the goal of use in the core only methods derived from the PSR interfaces, so as to give maximum flexibility and not be bound to an implementation rather than another.

Now i'm thinking about a routing system, and i'm wondered, how a so crucial component to web applications (used by all the frameworks) haven't a standard.

What do you think to propose it as a possible PSR?

Matthew Weier O'Phinney

unread,
Nov 17, 2016, 5:07:53 PM11/17/16
to php...@googlegroups.com
With Expressive, we've actually started down this direction already,
and Michael has been urging me to submit our ideas around this as well
as templating as potential recommendations.

Maybe take a look at zend-expressive-router and its RouterInterface,
Route class, and RouteResult as a place to start?
(https://github.com/zendframework/zend-expressive-router)

I'm certainly willing to discuss!


--
Matthew Weier O'Phinney
mweiero...@gmail.com
https://mwop.net/

Woody Gilk

unread,
Nov 17, 2016, 5:34:46 PM11/17/16
to php...@googlegroups.com
To me, the expressive implementation goes way beyond what a router does, which is:

Map an http method and a URI expression to a callable:

Router::add(method, urix, callable)
Router::get(urix, callable)
Router::post(...)
// etc for http methods

And then match a URI to a registered route:

Router::match(uri) : Route

Middleware is a totally separate thing and I think it's weird to put it here. Especially since middleware can do routing for you, no need for a separate step.


--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/CAJp_myW7zjLEFRhaNg4Qtz9gLFf4JWpfXwZcK2wszLCuiKS3Rw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
--

Damiano Petrungaro

unread,
Nov 17, 2016, 5:36:04 PM11/17/16
to PHP Framework Interoperability Group
Yes, imho this should be a good place to start, seeing also that zend is adopting it, this could be a good reference.
I'll look better the package tomorrow anyway.

We should think a way to abstract the Route and RouteResult value objects.

Message has been deleted

Damiano Petrungaro

unread,
Nov 17, 2016, 6:03:41 PM11/17/16
to PHP Framework Interoperability Group
I would like to avoid static methods, they are harder to test.
I prefer something (very basic example) like this


We should also discuss if is better to call the "add" method or "map".
I don't know which one is the most diffused.

I imagine like some interfaces like:
RouteInterface as representation of the single route,
RouterInterface as collector of Routes,
RouteMatcherInterface as object that can contains more RouterInterface that will match and dispatch the action.

Woody Gilk

unread,
Nov 17, 2016, 6:09:14 PM11/17/16
to PHP Framework Interoperability Group

I wasn't implying it should be static, just stating naming. I think I agree with you about the first two interfaces. What is the purpose of RouteMatcherInterface?



For more options, visit https://groups.google.com/d/optout.

Damiano Petrungaro

unread,
Nov 17, 2016, 6:24:12 PM11/17/16
to PHP Framework Interoperability Group
I didn't realize that you meant only the naming, my fault.

Anyway i imagine the RouterMatcherInterface as an object that will contains one or more RouterInterface, and handle the matching of the uri with a Route and will invoke the callable.

Example having different RouterInterfaces, the RouterMatcherInterface could prefer to use one of many.

So the routing system will be able to handle different RouterInterfaces implementation.

Maybe i am just over engeneering the moment of dispatching.

Woody Gilk

unread,
Nov 17, 2016, 7:39:02 PM11/17/16
to PHP Framework Interoperability Group
What would the use case for that be? I've never seen a system that worked that way.


See comment at the end for implied usage.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+unsubscribe@googlegroups.com.

To post to this group, send email to php...@googlegroups.com.

Hari K T

unread,
Nov 18, 2016, 12:27:46 AM11/18/16
to PHP Framework Interoperability Group
I believe , we should allow Router to do one thing, finding / matching the route, generating the route.

Dispatching based on the route should be done by dispatcher.

If you are curious what I am talking consider looking into the examples https://github.com/auraphp/Aura.Dispatcher#closures-and-invokable-objects .

I believe that is the best way you can remove complexity of dispatching on the router.

Benni Mack

unread,
Nov 18, 2016, 1:06:20 AM11/18/16
to php...@googlegroups.com
Hey Hari,

On 18 Nov 2016, at 06:27, Hari K T <ktha...@gmail.com> wrote:

I believe , we should allow Router to do one thing, finding / matching the route, generating the route.
Well, I think it should exactly do one thing - namely finding/match the route. The generation is IMHO separate, and belongs to a route generator or even URI/URL generator.

I agree, dispatching is somewhere else on the implementation level...

Best,
Benni.

-- TYPO3 Core Team Leader
Support the project: http://typo3.org/donate/

Damiano Petrungaro

unread,
Nov 18, 2016, 8:01:30 AM11/18/16
to php...@googlegroups.com
What do you think about an interface that will be used by RouterInterface for dispatch an event using a specific method?
In this way the dispatching implementation will be bounded inside a single RouterInterface (so we could imagine different RouterInterfaces and everyone will have a RouterDispatcherInterface implemented).

It's ok to put the dispatching is somewhere else on the implementation level, but i would like to put it inside to PSR.

--
You received this message because you are subscribed to a topic in the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/php-fig/Fj0QoGB1xLU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to php-fig+u...@googlegroups.com.

To post to this group, send email to php...@googlegroups.com.

Paul Dragoonis

unread,
Nov 18, 2016, 4:54:52 PM11/18/16
to php...@googlegroups.com

Hello everyone,

I have been waiting to announce this until after I finish with PSR16, but there's no time like the present.

I have been working on the routing PSR for some time now, given my passion and experience at integrating 5 different routers into PPI Framework Engine.

I have spoke with a few others about this over the past while i.e: MWOP and others.

I would be happy to push forward this PSR, by way of Editor, by partnering up with someone (MWOP?), since we both have the experience at building routing interop engines.

On the basis that someone is willing to sponsor me.

What do we say, is it time to release the cracken ?

Many thanks,
Paul


On 18 Nov 2016 1:01 p.m., "Damiano Petrungaro" <damianop...@gmail.com> wrote:
What do you think about an interface that will be used by RouterInterface for dispatch an event using a specific method?
In this way the dispatching implementation will be bounded inside a single RouterInterface (so we could imagine different RouterInterfaces and everyone will have a RouterDispatcherInterface implemented).

It's ok to put the dispatching is somewhere else on the implementation level, but i would like to put it inside to PSR.

On Fri, Nov 18, 2016 at 7:06 AM Benni Mack <benjam...@gmail.com> wrote:
Hey Hari,

On 18 Nov 2016, at 06:27, Hari K T <ktha...@gmail.com> wrote:

I believe , we should allow Router to do one thing, finding / matching the route, generating the route.
Well, I think it should exactly do one thing - namely finding/match the route. The generation is IMHO separate, and belongs to a route generator or even URI/URL generator.

I agree, dispatching is somewhere else on the implementation level...

Best,
Benni.

-- TYPO3 Core Team Leader
Support the project: http://typo3.org/donate/

--
You received this message because you are subscribed to a topic in the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/php-fig/Fj0QoGB1xLU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to php-fig+unsubscribe@googlegroups.com.

To post to this group, send email to php...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/A8BB6ABD-75E9-4678-9180-F6EE02FA2A4E%40gmail.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+unsubscribe@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.

Woody Gilk

unread,
Nov 18, 2016, 4:56:45 PM11/18/16
to php...@googlegroups.com

It seems like the people are ready for it.


To unsubscribe from this group and all its topics, send an email to php-fig+u...@googlegroups.com.

To post to this group, send email to php...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/A8BB6ABD-75E9-4678-9180-F6EE02FA2A4E%40gmail.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.

To post to this group, send email to php...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
--

Woody Gilk

unread,
Nov 18, 2016, 11:19:06 PM11/18/16
to PHP Framework Interoperability Group
And if you have anything ready to share, I'd be interested to see it.

Cees-Jan Kiewiet

unread,
Nov 19, 2016, 11:52:03 AM11/19/16
to php...@googlegroups.com
Same here, would be very interested to see what Paul has in mind for a routing PSR

Larry Garfield

unread,
Nov 19, 2016, 12:49:34 PM11/19/16
to php...@googlegroups.com
Background: My primary experience with routing systems is the conversion of the Drupal 7 menu/routing system to the Drupal 8 Symfony-based routing system, and realizing the issues with the way most systems seem to do routing today. :-)

I am quite skeptical about a routing PSR at this point.  Routing could be based on a wide variety of inputs, not just the URL.  Not even just the request, although conceptually the non-request data (likely derived from it, but also including DB calls) could be added to the attributes array for later access.  Even then, producing "a callable" may also be limiting, as I've been questioning some of the decision we made in Drupal to allow arbitrary callables as a route handler (controller).

At this point I remain unconvinced that a Routing PSR would be viable unless it was super-trivial.  Even a Route definition object would be hard to standardize; Drupal has a lot more there than Symfony does, and we're based on the same underlying libraries.

I've not looked at what Expressive is doing or what Paul is proposing, but at this point it doesn't feel like an area with enough "natural standardization" for a PSR to be viable.

--Larry Garfield

Woody Gilk

unread,
Nov 19, 2016, 1:13:38 PM11/19/16
to PHP Framework Interoperability Group
Larry,

I think this may be a difference, or lack of clarity, with language. My interpretation is that this would be an HTTP Router proposal that would use HTTP Messages. My feeling is that this area is definitely open to standardization, as there are many "routing" packages that effectively do the same thing. 

That said, I am not necessarily convinced that a callable is the correct target. My only concern with allowing a "mixed" type is that it cannot be strongly typed at the interface level.

--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+unsubscribe@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.

Paul Dragoonis

unread,
Nov 19, 2016, 1:16:31 PM11/19/16
to php...@googlegroups.com
Hi Guys,

I'm busy with my 3 children over the weekend so I'll be back on on wagon on Monday.

To clarify: what I've been working on is a HTTP Router specification, that uses HTTP Messages standard, and the PSR Middleware standard.

Speak on Monday.

Many thanks,
Paul


Damiano Petrungaro

unread,
Nov 20, 2016, 8:22:18 AM11/20/16
to PHP Framework Interoperability Group
Larry, i've limited experience, i am a developer just since 2 years, but have you ever used a routing based on something that skips the request object?
Anyway, if your idea is to make a PSR router not only built for HTTP requests we're here to discuss about it.
We could build a strategy pattern on the RouterInterface so what the different inputs, i can just imagine many ways for do a "loose coupling" router.

Damiano Petrungaro

unread,
Dec 8, 2016, 6:17:40 PM12/8/16
to PHP Framework Interoperability Group
Any news Paul?
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.

To post to this group, send email to php...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/94ac60a2-02ce-8332-5778-59f0011c8c20%40garfieldtech.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.

To post to this group, send email to php...@googlegroups.com.

Rasmus Schultz

unread,
Dec 29, 2016, 7:55:33 AM12/29/16
to PHP Framework Interoperability Group
Just my two cents, guys.

I don't think abstracting routers at a low level makes sense.

If I've selected a particular router, I've most likely selected it based on it's features in terms of configuration - standardizing on how routers are configured practically eliminates any reason to select any particular router, since you end up having to treat them all as precisely the same thing. Basically the only difference they can offer then, is performance.

To give you a practical example, here's an entirely different router-concept:


This router doesn't even define routes up front - a sub-route doesn't even exist before you attempt to resolve it's parent route. Obviously this isn't going to fit with any sort of standard interface for configuration, and certainly not the one used in zend-expressive. It's an entirely different concept from most routers.

With regards to route-resolution, I'm thinking, what is the purpose of abstracting route-resolution? Being able to dispatch the controller, presumably - whatever a "controller" may be. I think everything else can be regarded as implementation details.

So it would be possible to abstract this at a very high level - a router is something that takes a request and may or may not produce a response. But that sounds exactly like middleware.

Why or how is middleware not enough abstraction for router dispatch?

What's the advantage to abstracting routers in more detail? When do I need it? Why?

Why or how is "not being being to a specific implemention" of a router an advantage?

Or flip the question and say, when/why/how is it a disadvantage to be bound to a particular router with a particular set of features?

Why would I care which router I'm using if they all have to work the same? I would want the fastest one then. End of discussion right?

In my opinion, you may be trying to standardize something that's going to erase the differences, or the reason to have different routers in the first place, to the point where really one implementation would be enough - there would be no reason to have or use more than one router, anywhere, ever.

My problem with that is, if you picked a router like mine (above) you picked it because you like the concept, the idea.

If you reduce routing to "one idea", there's no way it's going to have room for different concepts such as this one. Is there?

Damiano Petrungaro

unread,
Dec 30, 2016, 11:17:30 AM12/30/16
to php...@googlegroups.com
So, for you, any PSR is wrong? (If is so this is a very strong assertion).

In my opinion the PSR is needed for some basic conpepts, and the router is one of this.


--
You received this message because you are subscribed to a topic in the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/php-fig/Fj0QoGB1xLU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to php-fig+u...@googlegroups.com.

To post to this group, send email to php...@googlegroups.com.

Rasmus Schultz

unread,
Dec 30, 2016, 11:50:32 AM12/30/16
to php...@googlegroups.com
So, for you, any PSR is wrong?

I have been pretty heavily invested in the development of PSR-5 and PSR-15, and I rely on PSR-7 and others in my work every day.

So no.

If you're trying to dismiss my opinion without actually debating any of the points I made, that's not the way to go about it.

PSR standards, in my view, are about making things interoperable - not about reducing every domain entity to a lowest common denominator.

To give you a few practical examples, the cache PSRs do not specify how a cache is implemented or configured, only how it's consumed. The middleware PSR does not specify how middleware is implemented or how the components get created, only how they're dispatched. The logger PSR does not concern itself with how loggers are implemented, routed, configured, created, etc. - only how the logger works once it's created, configured and ready to use.

If a router PSR defines how routers are configured as well as how they're consumed, how is it you think any logger will be able to differ from another, in the way it's configured, the features it offers, or anything else that makes one logger conceptually or feature-wise different from any other logger?

If you standardize router configuration, you've standardized the actual feature-set. There will be no practical reason (beyond performance) to choose any one specific implementation over another - they will all do precisely the same thing.

The same is not true for things like logging frameworks, cache back-ends or middleware.

Reducing all practical use of all routers to a lowest common denominator is meaningless. If you do that, you only need one router, the fastest one - it doesn't matter if they have different routing-configuration features beyond the standardized feature-set, you won't be able to use them.

Being able to dispatch a router without knowing how it was configured or created is, yes, important - but the same is true for lots of other components which take a request and produce a response, and middleware already takes care of that.

So I genuinely don't understand what it is you're trying to accomplish.

In my honest opinion, it sounds like a solution looking for a problem.


To unsubscribe from this group and all its topics, send an email to php-fig+unsubscribe@googlegroups.com.

To post to this group, send email to php...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/php-fig/0f2fb424-4d52-4e12-864f-fb039174a2e1%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to a topic in the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/php-fig/Fj0QoGB1xLU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to php-fig+unsubscribe@googlegroups.com.

To post to this group, send email to php...@googlegroups.com.

Daniel Plainview

unread,
Dec 30, 2016, 12:20:07 PM12/30/16
to PHP Framework Interoperability Group
Some things make frameworks special and routing, in my opinion, one of it.
If you want to eliminate this uniqueness among frameworks, you make pointless to choose between them.

> give maximum flexibility
> not be bound to an implementation

These are mutually exclusive statements.

Rasmus Schultz

unread,
Dec 30, 2016, 1:06:02 PM12/30/16
to PHP Framework Interoperability Group
Good point, thanks Daniel.

Here's another great example of a PSR with the right idea - the Container PSR, which is currently under review:


This does not attempt to erase the differences between containers - almost any container can support this interface, which makes the configured containers interoperable.

This PSR is excellent for comparison - the concepts, means and methods by which containers are configured are quite radically different, some (like Pimple) don't even use methods at all, so how could you possible standardize on an interface?

When it comes to resolving and checking for the existence of a dependency - actually using the configured container - they can all follow this standard, even minimalist Containers like Pimple can support it via an adapter.

Imagine for a moment if they had standardized on how containers are configured - you'd have the same situation I described above, there would be zero difference to select any container over any other, except performance, they would all need to do the exact same thing in the exact same way.

I think the situation is exactly the same with routers. What makes them different and individually useful or interesting, is what sort of facilities and features they offer in terms of configuration and creation.

If you take that away, there is zero reason to have more than one router or container, you would just want the fastest one, done.

A good PSR doesn't just reduce everything to the lowest common denominator - providing "maximum flexibility" means making room for things that are as different as, say, Pimple and PHP-DI, and abstracts only what is necessary in order to integrate those components in a consistent way.

You don't need to standardize how these components get created or configured - it's not important.

If your abstraction removes all the individual strengths and capabilities of each implementation, why would anyone want to implement it?

We might as well all agree on one router, then.

But that's never going to happen, just like we'll never agree on one DI container, one logging framework, one cache-server... that's not a realistic (or desirable!) goal.

Larry Garfield

unread,
Dec 30, 2016, 2:43:35 PM12/30/16
to php...@googlegroups.com
On 12/30/2016 10:50 AM, Rasmus Schultz wrote:
So, for you, any PSR is wrong?

I have been pretty heavily invested in the development of PSR-5 and PSR-15, and I rely on PSR-7 and others in my work every day.

So no.

If you're trying to dismiss my opinion without actually debating any of the points I made, that's not the way to go about it.

PSR standards, in my view, are about making things interoperable - not about reducing every domain entity to a lowest common denominator.

To give you a few practical examples, the cache PSRs do not specify how a cache is implemented or configured, only how it's consumed. The middleware PSR does not specify how middleware is implemented or how the components get created, only how they're dispatched. The logger PSR does not concern itself with how loggers are implemented, routed, configured, created, etc. - only how the logger works once it's created, configured and ready to use.

If a router PSR defines how routers are configured as well as how they're consumed, how is it you think any logger will be able to differ from another, in the way it's configured, the features it offers, or anything else that makes one logger conceptually or feature-wise different from any other logger?

If you standardize router configuration, you've standardized the actual feature-set. There will be no practical reason (beyond performance) to choose any one specific implementation over another - they will all do precisely the same thing.

The same is not true for things like logging frameworks, cache back-ends or middleware.

Reducing all practical use of all routers to a lowest common denominator is meaningless. If you do that, you only need one router, the fastest one - it doesn't matter if they have different routing-configuration features beyond the standardized feature-set, you won't be able to use them.

Being able to dispatch a router without knowing how it was configured or created is, yes, important - but the same is true for lots of other components which take a request and produce a response, and middleware already takes care of that.

So I genuinely don't understand what it is you're trying to accomplish.

In my honest opinion, it sounds like a solution looking for a problem.

I generally agree with Rasmus here.  Interface PSRs work best when the client library consuming it really only has one meaningful way to interact with the Thing (or the ways to do so can be reduced to one meaningful way with little to no loss of functionality), but there could be a variety of different implementations of the Thing for reasons other than "there are many like it, but this one is mine."  Logging is an extremely good fit for that.  Caching is a reasonable fit for that.  HTTP messages are a decent fit for that.  Routing?  I don't see that as fitting that model.

--Larry Garfield

Paul Dragoonis

unread,
Dec 31, 2016, 12:26:45 PM12/31/16
to php...@googlegroups.com


On Thu, Dec 8, 2016 at 11:17 PM, Damiano Petrungaro <damianop...@gmail.com> wrote:
Any news Paul?

Yeah, I have it here, but held back on releasing it just yet because I was busy finishing PSR-16, and then Christmas happened :)

Expect something in the next few days.


 
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+unsubscribe@googlegroups.com.

To post to this group, send email to php...@googlegroups.com.

Damiano Petrungaro

unread,
Apr 27, 2017, 11:04:05 AM4/27/17
to PHP Framework Interoperability Group
News about it?

Majid abdolhosseini

unread,
Sep 1, 2018, 6:37:37 AM9/1/18
to PHP Framework Interoperability Group
I almost agree with what you said,
just static call in my mind is not best practice.
and also for matching we should, we should be able to give uri or request object to match function.

because I belive in some cases uri and http method are not only options we make our matching strategy based on them.
for example consider based on "accept-lang" header or ... you want to have different callables.


$router->add(method, 'uri', callable)

$router->get('uri', callable)
$router->post(...)


$router->match($request)

Reply all
Reply to author
Forward
0 new messages