Hey logic_earth, thanks for actually discussing this and not just tossing out code. It’s been a while since I’ve actually had a proper discussion. If you will, allow me to explain my stance on this.
Take the following urls:
Author/Retire/42
Book/Publish/42
While I could use a generic pattern like “{controller}/{action}/{id}” there are problems with this approach. For starters, the pattern will resolve as a match for Book/Retire/42, which doesn’t make sense. While true that post resolution error checking will catch this, I find it a rather unacceptable scenario.
Consider how these would be registered:
$routes-Add(
'route_name',
'{controller}/{action}/{id}',
null, // no reasonable defaults
array(
'controller' => 'author|book',
'action' => 'list|add|edit|remove|publish|retire|retitle|rename'
)
);
As you can see, there is no consideration for which action values are paired with which controller. The only solution is to make two routes:
$routes-Add(
'author',
'Author/{action}/{id}',
null, // no reasonable defaults
array(
'controller' => 'author',
'action' => 'list|add|edit|remove|retire|rename'
)
);
$routes-Add(
'book',
'Book/{action}/{id}',
null, // no reasonable defaults
array(
'controller' => 'book',
'action' => 'list|add|edit|remove|publish|retitle'
)
);
Now, things make a bit more sense. But as you can see, the idea of a more granular style of routing is beginning to creep in. The next issue is that not all of the given actions will require an id. While most commercial systems account for this, in coding my own, I found it difficult to make considerations for the trailing ‘/’ separator. Assuming I can’t justify the extra time and coding required, we need more routes:
$routes-Add(
'author_with_id',
'Author/{action}/{id}',
null, // no reasonable defaults
array(
'controller' => 'author',
'action' => 'edit|remove|retire|rename'
)
);
$routes-Add(
'author_without_id',
'Author/{action}',
null, // no reasonable defaults
array(
'controller' => 'author',
'action' => 'list|add'
)
);
$routes-Add(
'book_with_id',
'Book/{action}/{id}',
null, // no reasonable defaults
array(
'controller' => 'book',
'action' => 'edit|remove|publish|retitle'
)
);
$routes-Add(
'book_without_id',
'Book/{action}',
null, // no reasonable defaults
array(
'controller' => 'book',
'action' => 'list|add'
)
);
We’ve now become much more granulated than we started out. But there is one last issue that really stands out. When integrating legacy code, we often come across controller and action names that do not follow proper conventions. We could spend some time refactoring this code, but depending on how large the code base is, it would probably be a lot easier to simple remap things such that our urls can be used without changing anything except the mapping code. In the above examples, the controller builder would look for AuthorController and BookController respectively. In order to decouple a given url from the intended controller and action, we must also remove these dependencies from the pattern. Doing so forces us to create a route for each controller/action combination we have in the system. This is not entirely unreasonable. If you think about how we handle dependency injection, mapping a particular interface to a particular class, then it makes sense to map a particular url to a particular controller and action. While increasing the number of routes we must define, it greatly reduces the complexity of the code, internal to the router itself.
// simple mapping with one variable
$routes->Add(
'book_publish',
'Book/{bookId}/Publish',
array('bookId' => '\\d+')
'Book',
'Publish'
);
// remapping a controller and action
$routes->Add(
'customer_remove',
'Customer/{customerId}/Remove',
array('customerId' => '\\d+')
'Cust', // using legacy controller name
'Delete' // using legacy action name
);
One final note is that most commonly available systems are written with general development in mind. They simply can not afford to make any assumptions on coding standards, methodologies, and conventions. However, these system are laden with code and conventions that may never be used in a professional environment, as most companies will define their own standards and code around them.
Hopefully, with all this mind, you can now understand why I see no reason to entertain the notion of default values for pattern variables, or including controller and action as variables in a pattern.