Code Bright: Basic Routing

← Back to Index

This title was written for Laravel version 4. If you're looking for material on the latest version of Laravel, then please check out Code Smart.

You are on a long, straight mud path out in the wilderness of... What country has a wilderness? Australia! That will do.

Don't freak out! This section requires a little imagination, so work with me on this one. I suppose our main character should have a name because books seem to do that. Hmm... let's call him Browsy Mc'Request.

Browsy Mc'Request is walking along a straight, muddy, path somewhere in kangaroo country. Browsy isn't a native to this land and has found himself lost with no idea where he is heading. He does, however know where he wants to be. A friend had earlier told him about “Jason Lewis' Shelter for Moustached Marsupials”. He knows that Movember is fast approaching and the Kangaroo stylists will need all the help they can get.

All of a sudden, Browsy spots what looks like a fork in the road way off in the distance. Excited at seeing anything other than his old familiar straight, muddy path, he sprints towards the fork hoping he might find some kind of direction.

Upon reaching the fork, he searches high and low for any indication of which path might lead to the shelter, but finds nothing.

Fortunately for Browsy, at that exact moment, a wild web developer appears. The strong and handsome web developer slams a signpost into the tough, dry dirt with ease, and dashes away in the blink of an eye.

Browsy is left dumbfounded by both the speed and rugged handsomeness of the web developer. Did I mention he was handsome? The web developer... not Browsy. Browsy looks kind of like THAT GUY from THAT BOOK who keeps saying 'my precious' a lot. At least that's how I see it.

After catching his breath, Browsy begins to study the signpost.

To the left you will find “Bob's Bobcat Riding Stables”, and to the right... ah! Here we go. To the right you will find “Jason Lewis' Shelter for Moustached Marsupials”.

Browsy eventually found his way to the Marsupial Shelter and lived a long and happy life learning to groom the many types of moustaches that kangaroos are able to grow.

You see, the moral of the story is that without a (HANDSOME) developer showing him the way, Browsy Mc'Request wouldn't have found his way to our applic… to the Marsupial Shelter.

Just like in the story, a web browser request wouldn't be directed to your application logic without some form of routing.

Basic Routing

Let's take a look at a request being made to the Laravel framework.

http://domain.com/my/page

In this example, we are using the http protocol (used by most web browsers) to access your Laravel application hosted on domain.com. The my/page portion of the URL is what we will use to route web requests to the appropriate logic.

I'll go ahead and throw you in at the deep end. Routes are defined in the app/routes.php file, so let's go ahead and create a route that will listen for the request we mentioned above.

<?php

// app/routes.php

Route::get('my/page', function() {
    return 'Hello world!';
});

Now enter http://domain.com/my/page into your web browser, replacing domain.com with the address to your Laravel application. This is likely localhost.

If everything has been configured correctly, you will now see the words 'Hello world!' in wonderful Times New Roman! Why don't we have a closer look at the route declaration to see how it works.

Routes are always declared using the Route class. That's the bit right at the start, before the ::. The get part is a method on the route class that is used to 'catch' requests that are made using the HTTP verb 'GET' to a certain URL.

You see, all requests made by a web browser contain a verb. Most of the time, the verb will be GET, which is used to request a web page. A GET request gets sent every time you type a new web address into your web browser.

It's not the only request though. There is also POST, which is used to make a request and supply a little bit of data with it. These are normally the result of submitting a form, where data must be sent to the web server without displaying it in the URL.

There are other HTTP verbs available as well. Here are some of the methods that the routing class has available to you:

<?php

// app/routes.php

Route::get();
Route::post();
Route::put();
Route::delete();
Route::any();

All of these methods accept the same parameters, so feel free to use whatever HTTP verb is correct in the given sithation. This is known as RESTful routing. We will go into more detail on this topic later. For now, all you need to know is that GET is used to make requests, and that POST is used when you need to send additional data with the request.

The Route::any() method is used to match any HTTP verb. However, I would recommend using the correct verb for the sithation you are using it in to make the application more transparent.

Let's get back to the example at hand. Here it is again to refresh your memory:

<?php

// app/routes.php

Route::get('my/page', function() {
    return 'Hello world!';
});

The next portion of the snippet is the first parameter to the get() (or any other verb) method. This parameter defines the URI that you wish the URL to match. In this case, we are matching the URI my/page.

The final parameter is used in this instance to provide the application logic to handle the request. Here we are using a Closure, which is also known as an anonymous function. Closures are simply functions without a name that can be assigned to variables, as with other simple types.

For example, the snippet above could also be written as:

<?php

// app/routes.php

$logic = function() {
    return 'Hello world!';
};

Route::get('my/page', $logic);

Here we are storing the Closure within the $logic variable, and later passing it to the Route::get() method.

In this instance, Laravel will execute the Closure only when the current request is using the HTTP verb GET and matches the URI my/page. Under these conditions, the return statement will be processed and the “Hello world!” string will be handed to the browser.

You can define as many routes as you like, for example:

<?php

// app/routes.php

Route::get('first/page', function() {
    return 'First!';
});

Route::get('second/page', function() {
    return 'Second!';
});

Route::get('third/page', function() {
    return 'Potato!';
});

Try navigating to following URLs to see how our application behaves.

http://domain.com/first/page
http://domain.com/second/page
http://domain.com/third/page

You will likely want to map the root of your web application. For example..

http://domain.com

Normally, this would be used to house your application’s home page. Let's create a route to match this.

<?php

// app/routes.php

Route::get('/', function() {
    return 'In soviet Russia, function defines you.';
});

Hey, wait a minute! We don't have a forward slash in our URI?!

CALM YOURSELF READER! You are becoming frantic.

You see, a route containing only a forward slash will match the URL of the website, whether it has a trailing backslash or not. The route above will respond to either of the following URLs.

http://domain.com
http://domain.com/

URLs can have as many segments (the parts between the slashes) as you like. You can use this to build a site hierarchy.

Consider the following site structure:

/
/books
    /fiction
    /science
    /romance
/magazines
    /celebrity
    /technology

OK, so it's a fairly minimal site, but a great example of a structure you will find often on the web. Let's recreate this using Laravel routes.

For clarity, the handling Closure of each route has been truncated.

<?php

// app/routes.php

// home page
Route::get('/', function() {});


// routes for the books section
Route::get('/books', function() {});
Route::get('/books/fiction', function() {});
Route::get('/books/science', function() {});
Route::get('/books/romance', function() {});

// routes for the magazines section
Route::get('/magazines', function() {});
Route::get('/magazines/celebrity', function() {});
Route::get('/magazines/technology', function() {});

With this collection of routes, we have easily created a site hierarchy. However, you may have noticed a certain amount of repetition. Let's find a way to minimise this repetition, and thus adhere to DRY (Don't Repeat Yourself) principles.

Route Parameters

Route parameters can be used to insert placeholders into your route definition. This will effectively create a pattern in which URI segments can be collected and passed to the application’s logic handler.

This might sound a little confusing, but when you see it in action everything will fall into place. Here we go...

<?php

// app/routes.php

// routes for the books section
Route::get('/books', function()
{
    return 'Books index.';
});

Route::get('/books/{genre}', function($genre)
{
    return "Books in the {$genre} category.";
});

In this example, we have eliminated the need for all of the book genre routes by including a route placeholder. The {genre} placeholder will map anything that is provided after the /books/ URI. This will pass its value into the Closure’s $genre parameter, which will allow us to make use of this information within our logic portion.

For example, if you were to visit the following URL:

http://domain.com/books/crime

You would be greeted with this text response:

Books in the crime category.

We could also remove the requirement for the book's index route by using an optional parameter. A parameter can be made optional by adding a question mark (?) to the end of its name. For example:

<?php

// app/routes.php

// routes for the books section
Route::get('/books/{genre?}', function($genre = null)
{
    if ($genre == null) return 'Books index.';
    return "Books in the {$genre} category.";
});

If a genre isn't provided with the URL, then the value of the $genre variable will be equal to null, and the message Books index. will be displayed.

If we don't want the value of a route parameter to be null by default, we can specify an alternative using assignment. For example:

<?php

// app/routes.php

// routes for the books section
Route::get('/books/{genre?}', function($genre = 'Crime')
{
    return "Books in the {$genre} category.";
});

Now if we visit the following the following URL:

http://domain.com/books

We will receive this response:

Books in the Crime category.

Hopefully, you are starting to see how routes are used to direct requests to your site, and as the 'code glue' that is used to tie your application together.

There's a lot more to routing. Before we come back to that, let's cover more of the basics. In the next chapter we will look at the types of responses that Laravel has to offer.

My books are available online for free to encourage learning. However, if you'd like for me to keep writing, then please consider buying a digital copy over at Leanpub.com.

It's available in PDF, ePub, and Kindle format, and contains a bunch of extras that you won't find on the site. I have a full-time job, and I write my books in my spare time. Please consider buying a copy so that I can continue to write new books from the comfort of my sofa!