Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Proposed routing changes for 3.0
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  3 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
mark_story  
View profile  
 More options Jul 22 2012, 10:04 pm
From: mark_story <mark.st...@gmail.com>
Date: Sun, 22 Jul 2012 19:04:37 -0700 (PDT)
Local: Sun, Jul 22 2012 10:04 pm
Subject: Proposed routing changes for 3.0

The Router is an important, powerful and frequently used piece of CakePHP.
 It is not without its problems though.  For 3.0, I've spent sometime
fixing many of the problems in router and adding missing functionality.

### Problems

* Reverse routing is slow.  With many connected routes, reverse routing can
be slow, as its a linear search across all connected routes.
* Named parameters are a mess.  They are an unconventional way to build
URL's that aren't implemented or supported by any other tools. They break
the ideas of 'convention over configuration', as they are not a convention
shared anywhere else on the internet.  This makes it difficult for other
tools to parse and generate. In addition to this, named parameters incur
some overhead when routes are matched, as various filtering steps are
required.
* Prefixes are poorly implemented.  I feel that prefixes could be better
implemented as sub-namespaces.  This would result in smaller, easier to
test code as admin/other methods are separate and contained.

#### Named routes

Named routes, even if the names are not entirely unique, can speed up
reverse routing.  By reducing the set of routes that needs to be traversed.
 Using a bucketed array, routes with the same name could be put into sets
that could be traversed.  If no names are provided, a linear search would
be done.

Names could be explicit, or generated based on the route template.

<?php
// Explicit name.
Router::connect('/:controller/:action/*', [], ['_name' =>
'_controller::_action']);
Router::connect('/login', ['controller' => 'users', 'action' => 'login'],
['_name' => 'login']);

// Generated name. Results in 'posts::_action'
Router::connect('/posts/:id/:action', ['controller' => 'posts']);

Generated names use the controller + action to create a name.  If a
controller action has multiple routes that point to it, those routes are
added to a single collection.  When reverse routing only the routes for a
given plugin.controller::action are considered.  In many cases this will
only match against one route.  Routes also fallback in a reliable order.
 If `['controller' => 'posts', 'action' => 'index']` was matched the
following keys would be attempted:

* posts:index
* posts:_action
* _controller:_action

Plugin routes fallback in a similar fashion but with the Plugin prefix
always present. For example:

* assetcompress.asset:get
* assetcompress.asset:_action
* assetcompress._controller:_action
* _controller:_action

### Special route keys

Currently url arrays support a few special keys.  The special keys should
be expanded to contain the following:

* `ssl` - Set to true.  Basically a shortcut for `_scheme => https`.  Can
be set to false to convert the scheme to http.
* `_scheme` - Defaults to the current request's scheme.  Would be used for
creating https, or webcal links for example.
* `_host` - The host to use, defaults to the current host.
* `_port` - Defaults to the current requests' port.  Would be used for
running SSL on un-conventional ports.
* `_full` - Set to true to include the full protocol, port and domain.
(Defaults to false)
* `_base` - Set to false to return an application relative path.
 Application relative paths are missing the subdirectory the application is
running in.  This is useful for making sub requests.
* `_ext` - The extension used for the url ie. `json` for `.json` urls.
* `#` - Create fragment identifiers.

All special keys except `#` are prefixed with a `_`.  This is to prevent
overlap with userland route elements.  As long as none of the following
keys are used generated urls will be domain relative (ie.
`/dir/controller/action`) `_scheme`, `_port`, `_host`, `_full`.

### Reverse Routing examples

<?php
// foo is unknown, and not a route element.
// This url uses the _controller:_action default route.
// so the extra params become a query string parameter.
Router::url(['controller' => 'posts', 'action' => 'index', 'foo' => 'bar']);
// Creates /posts/index?foo=bar

// Create a url for App\Controller\Admin\PostsController.
Router::url([
  'prefix' => 'admin',
  'controller' => 'posts',
  'action' => 'index',
  'lang' => 'en'
]);
// Creates /admin/posts/en/index

// Use a name for the route.
Router::url('login');

Router::url() has two valid signatures:

<?php
Router::url($name, $params);
Router::url($params);

Using named routes lets you more tersely express routes that would require
long sets of parameters in normal routing arrays.  Additionally using
unique names for all routes reduces the time to lookup routes to almost
nothing.

If no explicit name is used, a name will be generated based on the routing
parameters and used to look at a smaller route set.  This will speed up
route lookups, but has the potential to incorrectly choose routes.  In
these situations its best to use explicit names for routes.

### Prefixed actions

Prefixed actions have historically been implemented as prefixes to method
names. I feel this has a few drawbacks:

* Action names must be munged and combined with prefixes to create callable
methods names.
* Prefixed actions have special code to protect them from direct URL access.
* Prefixes have special code to handle them when generating urls.
* Prefixes require 2 parameters in calls to Router::connect().
* Prefixed actions are in the same class as the non-prefixed actions.  This
creates enormous classes that are generally handling multiple aspects of an
application.  Having both the admin and non-admin actions in the same class
increases the risk of accidentally making mistakes related to privilege
escalation.  By using components, traits, and inheritance code reuse (the
main benefit of having prefixes in the same class) could be achieved.

#### New implementation

Prefixes directly map to separate namespaces inside a plugin/app.  A
routing key would be used to indicate the prefix.  Possible options are
`_prefix`, `_ns`, `_namespace`, `prefix`, `namespace`.

<?php
// Route connection (using `prefix`)
Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));

// generate a url
Router::url(['controller' => 'posts', 'action' => 'index', 'prefix' =>
'admin']);

// The above resolves to.
App\Controller\Admin\PostsController::index()

Prefixes are `Inflector::camelize()` d before being combined into a
namespace.  This allows for multi-word prefixes.  Prefixes in plugins would
work in a similar way:

<?php
// Route connection (using `prefix`)
Router::connect(
  '/admin/contacts/:controller/:action/*',
  ['prefix' => 'admin', 'plugin' => 'contacts']
);

// generate a url
Router::url([
  'plugin' => 'contacts',
  'controller' => 'users',
  'action' => 'index',
  'prefix' => 'admin'
]);

// The above resolves to.
Contacts\Controller\Admin\UsersController::index()

The `prefix` key could be set to `false` to force a route to generate as a
non-prefixed method.  The `Routing.prefixes` Configure var would still be
available to declaratively configure which prefixes are going to be
connected by the default routes.

#### View files

All view files would be located in paths similar to the controllers.  So if
your controller was `App\Controller\Admin\ContactsController` the view
files would be in `App/View/Admin/Contacts/` by convention.  Of course you
can change this using `Controller::$viewPath`.  Prefix controllers with
alternate formats would follow the convention of
`App/View/Admin/Contacts/{xml,json}/`.

I apologize for the long winded post, if anyone is interested in the
changes you can see the branch diff at:

https://github.com/cakephp/cakephp/compare/3.0...3.0-router

If anyone has any feedback, I'd love to hear it so I can integrate the
feedback and merge this into 3.0.

-Mark


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
ADmad  
View profile  
 More options Aug 3 2012, 10:13 am
From: ADmad <admad.co...@gmail.com>
Date: Fri, 3 Aug 2012 07:13:04 -0700 (PDT)
Local: Fri, Aug 3 2012 10:13 am
Subject: Re: Proposed routing changes for 3.0

Mark, will Router::url() will now be able to generate full urls without
protocol like "//somedomain.com/foo/bar" ?


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
mark_story  
View profile  
 More options Aug 4 2012, 1:58 pm
From: mark_story <mark.st...@gmail.com>
Date: Sat, 4 Aug 2012 10:58:55 -0700 (PDT)
Local: Sat, Aug 4 2012 1:58 pm
Subject: Re: Proposed routing changes for 3.0

I don't think that's possible right now.  Only domain relative urls are
currently supported.  It shouldn't be overly arduous to add protocol
relative urls though.

-Mark


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »