dasprid / dash Goto Github PK
View Code? Open in Web Editor NEWFlexible PSR-7 compliant HTTP router
License: BSD 2-Clause "Simplified" License
Flexible PSR-7 compliant HTTP router
License: BSD 2-Clause "Simplified" License
As of
, the route is built and then modified.It would be better to pass in an options object to allow strictness, or alternatively to pass in the array of correct keys at construct time to remove any kind of overhead
You are using uasort but it's pretty slow. I think you can reorder those lines: https://github.com/DASPRiD/Dash/blob/master/src/Dash/Mvc/Router/Http/RouteCollection/RouteCollection.php#L66
so that priority comes first, then serial, then route. This way you can directly use sort without having to rely on a custom method.
Can gain some minor improvements by just checking if the array is empty via:
public function isEmpty()
{
return ! $this->routes;
}
It's sometimes used in REST APIs for partial resource updates.
Hello,
This will probably go down very badly, but I'd like to propose we change the ordering of the numerical indexed shortcut parameters from path, controller, action, methods
to path, action, controller, methods
. "Why?" I hear you ask. "This is madness!" I hear you jeer, but please, hear me out.
Firstly, let's make something plain. Flipping the order of controller and action is counter-intuitive. I understand that. But I feel that the new order will make hierarchical routes easier to define.
Take the following route declaration:
'profile' => ['/profile', 'profile', 'index', 'children' => [
'messages' => ['/messages', null, 'messages''],
'details' => ['/details', null, 'details'],
'view_message' => ['/message/:id', null, 'view-message', 'constraints' => ['id' => '\d+']],
]],
See all those horrible nulls you have to pass so that the route inherits it's parents controller? Using my method, they can safely be avoided thus:
'profile' => ['/profile', 'index', 'profile', 'children' => [
'messages' => ['/messages', 'messages''],
'details' => ['/details', 'details'],
'view_message' => ['/message/:id', 'view-message', 'constraints' => ['id' => '\d+']],
]],
Is this enough of a win to justify doing something people won't expect? I'll let you decide.
Thanks for reading.
As of
, getters can be avoided. Direct property access is perfectly ok in the implementation of the method.Numeric indexes are useful for writing less, but you still need to remember the correct order. Associative indexes allow the values to be placed in any order and are much easier to be overloaded.
Hi @DASPRiD ,
I was looking into dash, and noticed it is making use of zf2 uri component.
Is it really needed?
If you look uri, it makes use of
"zendframework/zend-escaper": "self.version",
"zendframework/zend-validator": "self.version"
I have looked at some of the routing libraries like aura, symfony etc. But haven't noticed something like a uri is really needed. Is there any extra behavior I am missing to understand ?
It may be good if router can reduce the amount of components which are not really needed.
Thank you
It seems that Dash is limited to HTTP only.
That will screw up how we might write actions that work with other types of requests (i.e. console, worker, non-http RPC, deferred, etc.)
At the very least it should be clear, that it's a http-only thing and not "zf3 router"... but then the question is how are other types of requests routed (separate router?), how can we type-hint or consume other types of requests etc.
Currently, we do have a MatchResultInterface
, but that only defines whether the match was a success or not. But for anything further, the user has to make instanceof
calls against it, which is a little dirty.
While the match result architecture was build really flexible, it doesn't make much sense to have more return types than those which we have already defined. Now the question would be how we could model a generic match result, which fulfils the following requirements:
I'm open to any suggestions!
Please don't make it necessary to use actions. Actions are implementation specific and some don't use them.
https://github.com/zendframework/zend-mvc/tree/master/src/Router/Http
Just hoping you have that thought out, as it might screw up your current architecture.
There's tons of use-cases where those route types are required.
RouteCollection#insert()
could be faster by swapping the check with:
if (!($route instanceof RouteInterface || is_array($route))) {
}
Just to keep this noted (and before anyone else comes up with this :P):
*
As of RouteMatch#getParam()
, array_key_exists
is used.
Can instead do: isset
to speed it up:
if (isset($this->params[$key]) || array_key_exists($key, $this->params)) {
}
See https://tools.ietf.org/html/rfc6570 - much better than yet another custom format
Could that be implemented as a single route type?
Implementing IteratorAggregate is much faster than implementing any iterator interface (because PHP needs to call around 5 custom functions at each iteration).
I'm wondering if you cannot implement IteratorAggregate, and do this in RouteCollection:
public function getIterator()
{
if (!$this->sorted) {
arsort($this->routes);
$this->sorted = true;
}
return new ArrayIterator($this->routes);
}
Hi,
In my refactor of ZfrRest, I stumbled into an interesting case, and I'd like to know if Dash supports that. Basically, I want to be able to set a template based on a route name. For instance, if there is a "users" route that has a child route called "user", it will be possible to decide to render a template for "users/user".
However, for correctly resolving the file path and find the proper file name, I need to have the default controller (because it contains the namespace that is needed to resolve the file). What I'd like to do is being able to do that:
$params = $router->getRouteForPath('users/user');
Or something similar, and it would return all the info from config for a given path (its defaults values, constraints)...
Is this possible @DASPRiD ?
Router#match()
uses internal state via getters
A faster solution may be:
if ($this->baseUri === null && ($request instance of PhpEnvironmentReques || method_exists($request, 'getBaseUrl'))) {
$this->baseUri = $request->getBaseUrl();
}
Hi,
It would be awesome if you could move some of your benchmark code directly into Dash. As a rule of thumb, I'd like if we could have this in ZF3 for all critical performance components. That would allow for much simpler optimization work (as we would have a true before/after), as well as being able to quickly have a look at the impact of a new feature on performance, and eventually rejecting it (I'm thinking here about input filter that has many features introduced, without taking care of performance, so now this component is really slow - if we had that we could have quickly rejected some feature, or refactoring them).
As of RouteMatch#setRouteName()
, some magic is happening in there. No-go atm
'zf2-match' => [
new Segment('/', '/[:a[/:b]]', ['a' => '[a-zA-Z][a-zA-Z0-9_-]*', 'b' => '[a-zA-Z][a-zA-Z0-9_-]*']),
'/indexA/indexB',
0,
['a' => 'indexA', 'b' => 'indexB'],
]
SegmentTest::testCompiling returns '/' but I was expecting it to return '/indexA/indexB', is this a bug?
https://github.com/DASPRiD/Dash/blob/2271fdbfdb7a627f22cb8cb51223a6ec1a98aeeb/src/Dash/Mvc/Router/Http/Parser/HostnameSegmentFactory.php uses static instances to save instantiation performance logic. Instead, simply sharing the hostname segment routes in the service container would be easier, cleaner and more flexible
That means that non-nullable properties are not guaranteed to be set.
Additionally, there's no real reason for the property to be static.
Its not entirely clear to me the purpose of the {}
delimiters, can you describe what the intention is, maybe with examples for {-}
and {-/}
?
For @DASPRiD: https://github.com/c9s/Pux
I know nothing about how this project work, it's full of obscure thing, but maybe it makes sense to you and it could give you some nice ideas to optimize Dash.
Hi everyone,
In ZF2, I am always confused about how I can prepend or append routes to routes that were defined by a third-party module. For instance, let's say a module provides the following route:
return [
'oauth' => ['/oauth', 'controller', 'action', 'children' => []]
];
Now, if I want to prepend each of those routes with a custom route (for instance an API base route), I'd suggest adding a "prepend" parameter:
return [
'oauth' => ['/oauth', 'controller', 'action', 'prepend' => 'api', 'children' => []]
];
The same can occur to append routes using the "append" keyword. Of course, when a prepend or append is added, the old route is not accessible anymore through its origin URL (so for instance oauth route is no longer accessible from "/oauth" but only from "/api/oauth".
Ping @Ocramius for syntax
In ZF2, people had to be explicit about how trailing slashes in URLs are handled by their routes. Our strictness there was rather pointless, as search engines will see two URLs as the same resource when one ends with a slash and one doesn't.
The proposed solution is to simply rtrim()
a possible trailing slash from the incoming path, except if the entire path only consists of a single slash.
Hi,
I don't remember if this is coded in Dash, but in ZF2, I always struggle very very hard with prepending a route to an existing route. You ahve to create "prototype", and used "chain_routes", which is very confusign. For Dash, I suggest a mapping like that:
return 'routes' => [
'my-hostname' => ['api.myapp.com'],
'users' => ['prepend' => 'my-hostname']
]
And boom.
Currently is really annoys me that Http/Console routes are separated in Zf2.
There is actually no reason for the RouteCollection and the Generic route to be mutable, and it currently requires a bit of defensive code. Thus I suggest to make them both immutable and thus the router again a lot simpler.
As of
Dash/tests/DashTest/Mvc/Router/Http/RouterFactoryTest.php
Lines 27 to 33 in 375ac6b
That is not acceptable due to the nature of Zend\Stdlib\ArrayUtils::merge()
I call this the "expressive routing language".
return [
'routes' => [
['GET|POST /users AS users', UserController::class] => [
['GET|PUT|DELETE /:id WITH id=[0-9]+ AS user', UserController::class, 'myAction'],
['GET /tweets AS tweets', TweetController::class]
]
]
];
I'm not sure static is needed here: https://github.com/DASPRiD/Dash/blob/master/src/Dash/Mvc/Router/Http/Parser/PathSegmentFactory.php#L52
What's the use case?
There's an useless call to Router#getRouteCollection()
in the RouterFactory
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.