
URL Routing in Recess my upcoming PHP Framework - KrisJordan
http://www.recessframework.com/page/routing-in-recess-screencast
======
raamdev
I'm really looking forward to Recess! I've been in the need of a PHP REST
Framework for a small project and Recess seems to be the closest thing to what
I need. All the other Frameworks seemed to have REST functionality "hacked"
in, instead of being built with REST in mind.

I can't wait! :)

------
ErrantX
Hey, that's pretty clever! It fixes some of the issues with "traditional" mvc
style routing (say in CI or K). Very impressed.

Also liking the deployment and dev modes & the tools app (which is a killer
feature IMO!).

How far off complete is it?

~~~
KrisJordan
Thanks - I'm really excited about the tools, personally.

Preview bits will go out to folks on the mailing list this week. There's a fun
road ahead in bringing the framework to maturity - but there 'core' meat of
the framework is solid and a nice departure from the current state of PHP
frameworks.

~~~
mk
I'm looking forward to this. I plan on giving a talk at work about frameworks
and would love to know more about Recess. Routing looks good so far.

------
Hexstream
Nice stuff.

Might you consider dropping the bang in "Recess!"? I can't imagine a more
annoying naming gimmick. It's not so bad when the name is used alone but it
really messes up the reading when it's in a paragraph.

~~~
KrisJordan
Duly noted. I've gone back and forth on the bang, you're right it really
screws up paragraph readability.

~~~
jraines
I agree. I think Recess by itself is an awesome, very catchy brand name for a
web framework.

------
petercooper
Looks very much like Sinatra - <http://sinatra.rubyforge.org/> \- PHPized.

In Sinatra you don't even need the methods. For example:

    
    
      get '/say/*/to/*' do
        # put code here
      end
    
      post '/somewhere_else' do
        # put code here
      end
    

If the original developer hasn't seen Sinatra it'd be worth checking out for
some ideas - Sinatra is becoming quite popular in Rubyland lately so the ideas
are reasonably sticky and probably worth porting to PHP.

~~~
KrisJordan
Not familiar with Sinatra. Will look into it, thanks!

------
DavidMcLaughlin
How would this handle backwards engineering?

When debugging an application someone else has written, generally I'll be
given a problem - and I want to find out all the code behind whatever is
broken or needs looked into. So you start from a URL, go to your centralised
dispatcher router whether that be your Zend bootstrapper, a mod_rewrite rule
in a .htaccess file, your django URLs file or.. whatever. From there you'll be
able to work out which controller and action you need to look at. In this case
I'm looking through a whole bunch of controllers and then their doccomments to
see which route matches. Not pleasant.

As someone said, this is pretty clever, but I'm not convinced it leads to
maintainable code. Which is the entire point of frameworks and the MVC
pattern. There are other ways to implement DRY in a dispatcher without
resorting to inlining a pattern into a comment. For example, you could
delegate a base pattern to another URLs conf like you do in django.. or use
nested routes like the Perl Mojolicious framework:

[http://search.cpan.org/~sri/Mojo-0.9/lib/Mojo/Manual/Mojolic...](http://search.cpan.org/~sri/Mojo-0.9/lib/Mojo/Manual/Mojolicious.pod)

~~~
ErrantX
He seems to have built a set of tools to handle this problem.

From the very brief sneak peek we got at that it looks like a killer toolset
for something lie what you describe. Knowing where to head to BEFORE even
opening a controller file is a big bonus :)

------
alexandros
wow, this looks impressive. how long did it take you to get this far?

Me and a friend are looking for a good php framework to build an application
on. Any idea on when this will be out?

The support for methods and paths is very cool. Is there any support for media
types/content negotiation?

~~~
KrisJordan
Recess has been in development, full-time, for about 3 months now. It all
began after returning from the Web 2.0 Expo in New York - reinvigorated about
the pragmatic utility of PHP by Cal Henderson (I now refer to his talk as my
PHP Tent Revival) and inspired by DHH and others about the beauty of RESTful
interfaces and the HTTP spec.

Content negotiation is on the radar. Currently the negotiation is one-sided
and depends on the request having a .json extension for example. This will be
beefed up after the preview release.

------
emmett
You've reinvented Lisp macros in PHP. I did the same thing Rails for caching;
this is a classic example of something macros make easy and natural.

~~~
cabalamat
"Any sufficiently complicated C or Fortran program contains an ad hoc,
informally-specified, bug-ridden, slow implementation of half of Common Lisp."
-- Philip Greenspun

------
akie
I really dig the simplicity of this approach, yet I think it's disaster
waiting to happen.

Essentially, you're moving a part of your functionality (the part that
determines which URLs exist, and which parameters are defined in those URLs)
from a programming language environment to a common language environment (the
comments). That common language environment is not as capable when it comes to
defining, specifying or altering functionality - but it's what a programming
language excels in.

So what do you do if you want to _generate_ URLs? Or if you want to define
URLs based on some content in the database? Those are hard things to
accomplish with your current approach. I assume that there's a proper API that
might address such issues, but the article doesn't mention such a thing. Good
luck though.

------
edb
This is actually pretty cool, but I'm genuinely curious why it's advantageous
to write the routes in the controller files instead of one central place
that's easily maintained?

CakePHP, (<http://book.cakephp.org/view/46/Routes-Configuration>) for example,
can do all of what this does out of the box without the need for an
application to monitor your routes.

REST also seems very well implemented :
<http://book.cakephp.org/view/476/REST>

Am I missing something? Can someone explain the benefits?

------
cosmo7
Hmm, so your routes are "structural comments." Isn't this what XML is for?

Am I the only one here who finds this ugly?

------
agotterer
What happens when you accidentally duplicate one and have to go through every
controller looking for the culprit?

~~~
JoelSutherland
This is covered in the screencast. One of the smart error messages that the
framework gives is the location of any duplicate routes.

~~~
agotterer
Guess I should have watched the whole thing :) Thanks.

------
senthil_rajasek
Hmmm nice work (around) don't you wish php had attributes support...

Have you thought about using "named" variables for this sort of functionality
without interfering with the commenting system.

~~~
mihasya
That was my first thought too, since the Reflection API lets you get to the
actual parameter names... However, I'm not sure off the top of my head how
pretty URL's would be implemented(probably would have to use mod_rewrite).
There's also the URL prefixes he's implementing. I think he's giving up the
efficiency of mapping _REQUEST params straight to arguments in favor of more
features/flexibility. My takes on frameworks went the former route (straight
mapping + mod_rewrite), but I've since become less hardcore about being
minimalistic with URL's.

~~~
KrisJordan
There is some additional overhead in mapping the the $_REQUEST params but it's
not actually so bad.

Design decisions have been made to err in the favor of making user code simple
and more expressive. Having some routing logic contained in the code and
'pretty urls' in mod_rewrite is much more difficult to approach.

~~~
mihasya
I'm not sure what you mean by additional overhead... You're already using the
Reflection API to to get to the names of the method arguments so that your
/hello/$first/$last works, no? Or are you just relying on the order and
assuming the developer puts things in teh right order, ie /hello/$foo/$bar
works just as well?

If the former is true (you're already getting the param names), then there's
no further overhead to map directly to $_REQUEST. I forget the exact
Reflection syntax, but wouldn't it just be something like

$argsToPass = array(); $args = ReflectionMethod->getParams(); //you got an
array of param names in the order they appear in the function foreach ($args
as $arg) { if (!isset($_REQUEST[$arg])) { //check if the arg is optional and
fail if not } $argsToPass[] = $_REQUEST[$arg]; }
$ReflectionMethod->invoke($argsToPass);

I haven't touched this stuff in a while, so I might be completely off, but I'm
not sure what overhead you're referring to...

Once again, I'm not defending this approach, as the extra logic you've put in
to interpret the path probably makes things a lot more flexible and easier to
debug.

~~~
KrisJordan
Thanks for clarifying and the code bit. This is very close to what's actually
going on. The 'overhead' I mentioned is minimal, and exactly what you
described.

The names are important in mapping so... / __!Route GET, $last/$first */
function foo($first, $last) {...} Maps $first to $first properly, etc.

Indeed the hope is that this will be easier to understand and use.

------
KevBurnsJr
Doc Comments, that's a new one.

<http://www.php.net/manual/en/language.oop5.reflection.php>

------
danw
This looks like it's going to be great. When can we get a hold of the code to
play with it?

------
wesley
Great! But "Smarty templating pover views"? Please don't!

~~~
mihasya
Why does everybody hate Smarty? Explain please.

~~~
shaunxcode
The trade off between wasted processing and elegance is not high enough for
most people. I could see it being nice if you are giving access to "non-
developers" to modify the views/templates of your system and want to make sure
they only have access to a given subset of functionality.

~~~
mihasya
Smarty compiles its templates, so only the first execution takes the
processing hit. If you have APC, the hit is also very small.

