Routing

Last updated: September 3rd, 2017

Introduction

The routing feature of TriTan, lets you map URI’s to HTTP request methods (GET, POST, PUT, DELETE, OPTIONS).

$app->match(method(s), pattern, function);

When a route matches, the attached route handling function will be executed. The route handling function must be a callable. Only the first route matched will be handled. When no matching route is found, an ‘HTTP/1.1 404 Not Found’ status code will be returned.

Shorthands for single request methods are provided:


$app->get('pattern', function() { … });
 
$app->post('pattern', function() { … });
 
$app->put('pattern', function() { … });
 
$app->delete('pattern', function() { … });
 
$app->options('pattern', function() { … });
 
$app->patch('pattern', function() { … });
                                        

There is also an alternative shorthand for request methods in the following format:


$app->route('HTTP Method', pattern, function);
                                        

Here are some shorthand examples to above:


$app->route('GET', 'pattern', function() { … });
 
$app->route('POST', 'pattern', function() { … });
 
$app->route('PUT', 'pattern', function() { … });
 
$app->route('DELETE', 'pattern', function() { … });
 
$app->route('OPTIONS', 'pattern', function() { … });
 
$app->route('PATCH', 'pattern', function() { … });
                                        

Another alternative to above is route matching. A particular code will run based on the HTTP Method sent.


$app->match('Piped Method', pattern, function);
                                        

Here is an example of using GET and POST.


$app->match('GET|POST', 'pattern', function() { … });
                                        

Route Patterns

Route patterns can be static or dynamic.

  • Static Route Patterns are basic URIs, e.g. /about.
  • Dynamic Route Patterns are Perl-compatible regular expressions (PCRE) that resemble URIs, e.g. /api/(\d+)

Commonly used subpatterns within Dynamic Route Patterns are:

  • \d+ = One or more digits (0-9)
  • \w+ = One or more word characters (a-z 0-9 _)
  • [a-z0-9_-]+ = One or more word characters (a-z 0-9 _) and the dash (-)
  • .* = Any character (including /), zero or more
  • [^/]+ = Any character but /, one or more

Downloading the PHP PCRE Cheatsheet may come in handy.

Subpatterns must be parenthesized in order to work. See example below:


use TriTan\Functions as func;

// Bad
$app->get('/hello/\w+', function($name) {
    echo 'Hello ' . func\_escape($name);
});
 
// Good
$app->get('/hello/(\w+)', function($name) {
    echo 'Hello ' . func\_escape($name);
});
                                        

When multiple subpatterns are defined, the route handling parameters are interpreted in the order which they are defined.


$app->get('/posts/(\d+)/photos/(\d+)', function($postId, $photoId) {
    echo 'Post #' . $postId . ', photo #' . $photoId);
});
                                        

Optional Route Subpatterns

Route subpatterns can be made optional by making the subpatterns optional by adding a ? after them. Think of blog URLs in the form of /blog(/year)(/month)(/day)(/slug):


$app->get('/blog(/\d+(/\d+(/\d+(/[a-z0-9_-]+)?)?)?)?', function($year = null, $month = null, $day = null, $slug = null) {
    // ...
}
                                        

Middleware

Before route/router middleware is code that must meet a condition before the route can be accessed. In the example below, we check to see if user is logged in and if the auth_token cookie is present for the user. If not, we redirect the user to the login screen.


use TriTan\Functions as func;

$app->before('GET|POST', '/admin/.*', function() use($app) {
    if (!isset($app->req->cookie['auth_token'])) {
        func\ttcms_redirect(func\get_base_url() . 'login' . '/');
        exit();
    }
});
                                        

Subrouting / Grouping Routes

Use $app->group($baseroute, $fn) to group a collection of routes onto a subroute pattern. The subroute pattern is prefixed onto all following routes defined in the scope. e.g. Mounting a callback $fn onto /posts will prefix /posts onto all following routes.

Request Methods

Every HTTP request has a method (i.e. GET or POST). You can obtain the current HTTP request method via the below request objects:


/**
 * What is the request method?
 * @return string (e.g. GET, POST, PUT, DELETE)
 */
$app->req->getMethod();
 
/**
 * Is this a GET request?
 * @return bool
 */
$app->req->isGet();
 
/**
 * Is this a POST request?
 * @return bool
 */
$app->req->isPost();
 
/**
 * Is this a PUT request?
 * @return bool
 */
$app->req->isPut();
 
/**
 * Is this a DELETE request?
 * @return bool
 */
$app->req->isDelete();
 
/**
 * Is this a HEAD request?
 * @return bool
 */
$app->req->isHead();
 
/**
 * Is this a OPTIONS request?
 * @return bool
 */
$app->req->isOptions();
 
/**
 * Is this a PATCH request?
 * @return bool
 */
$app->req->isPatch();
 
/**
 * Get host
 * @return bool
 */
$app->req->getHost();
 
/**
 * Returns GET variable if set
 */
$app->req->get[$caller];
 
/**
 * Returns POST variable if set
 */
$app->req->post[$caller];

/**
 * Returns COOKIE variable if set
 */
$app->req->cookie[$caller];

/**
 * Returns web server entries
 */
$app->req->server[$caller];