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.
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.
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.
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.
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:
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 :)
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.
"Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp." -- Philip Greenspun
Yes, the annotations essentially offer a simple macro functionality for PHP. In production mode they're reflected over once and then not touched again.
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.
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?
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.
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.
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.
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.
Yes - first class attribute support would be great. Late static binding (coming in PHP 5.3) will be nice once it is ubiquitous.
Attributes are a way of declaratively making a statement at a more "meta" level. Because doccomments are a first class language construct in PHP (i.e. Reflection provides doccomments for you) it seemed the most appropriate place for providing additional metadata.
Smarty templating is optional but easy to set up. Smarty seems to be a religious topic for PHP developers. Switching between Native views and Smarty views for a controller is done in a single annotation on a per controller basis.
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.
You're ignoring quite a few features of Smarty, and I disagree with you on human readability.
The other reply also wasn't saying anything about ease. It was about control, which is also important once your team reaches a certain size/level of skill diversity.
I can't wait! :)