Advanced Routing Techniques
Prev Chapter 8. Routing Requests Next

Advanced Routing Techniques

HTTP METHOD Aware Routes for RESTful Routing

Routing in Recess is HTTP method-aware. To demonstrate this we can have two controller methods mapped to the same URL but differing HTTP METHODs:

Example 8.4. Routing with different HTTP Methods

<?php
class TestController extends Controller {
    /** !Route GET, /same/url */
    function comingFromGet() {
         echo '<form action="/same/url" method="post">';
         echo '<input type="submit" /></form>'; exit;
    }
    /** !Route POST, /same/url */
    function comingFromPost() {
         echo 'POSTed!'; exit;
    }
}

The first method will handle a GET to the url /same/url and the second a POST to /same/url. For an actual demonstration of this running check out the screen cast at minute 7:00! Having a routing system aware of HTTP methods is one way in which Recess helps simplify RESTful application develop in PHP.

Relative Routes

In Recess, Routes can be relative to their context. What does that even mean? There are three logical levels of organization for the purposes of Routing. The most general level is the application. Recess allows multiple applications to be installed at once a la Django. Within an application there may be multiple controllers and a controller can have many methods.

Relative routes are different from absolute routes in that they do not begin with a forward slash. Check out the !Route annotation for the world method below. By adding a !RoutesPrefix annotation to a controller we will prepend any relative route in the controller with hello/ so we can now reach the world method using hello/world/.

Example 8.5. Relative routing in controller routes to hello/world.

<?php
/** !RoutesPrefix hello/ */
class TestController extends Controller {
    /** !Route GET, world */
    function world() {
         echo 'Hello World!'; exit;
    }
}

Implicit Routes

If you’re familiar with Rails or Cake you’re probably wondering why I needed specify routes for the world and universe methods. In many frameworks these routes would be implicit. In Recess they can be implicit too. We can delete the route annotations and still access the methods in the same way. The important difference between the way implicit routes work in Recess and other frameworks is that Recess does not rely on the name of a controller to determine the route, but rather on the routing prefixes of the application and the controller.

Example 8.6. Implicit routing in controller routes to hello/world.

<?php
/** !RoutesPrefix hello/ */
class TestController extends Controller {
    function world() {
         echo 'Hello World!'; exit;
    }
}

Because we've set up a route prefix for the TestsController we can reach the world method by using the URL: hello/world. Implicit routes can have parameters too.

Example 8.7. Implicit routing with parameters.

<?php
/** !RoutesPrefix hello/ */
class TestController extends Controller {
    function world($first, $last) {
         echo "Hello $first $last!"; exit;
    }
}

Now, hello/world/Michael/Scott will rest in the world method being called and printing "Hello Michael Scott!"

Recess Tools & Routing

With routes being sprinkled throughout controllers don’t you lose the ability to look in a single place and get a sense of all of the routes in your application?

Recess Tools is first class Recess application that runs in the browser and is designed to help you along in development mode writing apps. With Tools we can see all of the routes explicit and implicit, relative and absolute, for any given application. The table lists the HTTP method and route corresponding which map to a controller class and method. With Recess Tools you can get a global picture of Routes in your application.

Routing Performance

How in the world can you expect to get any kind of performance out of an app when you have to reflect over every single controller in order to know all routes?

This is a great question. Routing changes as shown in the screencast take immediate effect. This is because the screencast was taken while Recess was in development mode. By switching to deployment mode the routing computation would only have to happen once because the routes won’t change. On the first request in deployment mode Recess will build up the routing data structure, a tree, and cache it either to disk or memory depending on what your server has available. Subsequent requests simply unserialize the routing tree and Recess is off to the races. Perf has been a top priority while developing Recess and this technique enables great performance while allowing your code to stay simple, nimble, and DRY.


Prev Up Next
Chapter 8. Routing Requests Home Chapter 9. The Recess Controller