So I'm new to the Laravel framework as of v4 and wondering what is the way to create and use RESTful controllers. Reading through the documentation, I'm a bit confused as to the difference between RESTful controllers and Resource controllers.
When defining a RESTful controller, as per the docs, it suggests doing the following in routes.php
:
Route::controller('posts', 'PostController');
In the PostController
, do we define the class methods by prefixing the name of the method with the HTTP verb we should like to use? For example:
class PostController extends \BaseController {
public function getIndex()
{
//
}
}
However, it also outlines a way of creating Resource controllers in the routes.php
file like so:
Route::resource('posts', 'PostController');
And in PostController.php
we define methods without prefixing it with the HTTP verb.
class PostController extends \BaseController {
public function index()
{
//
}
}
What is the difference between the two? And when do we use one instead of the other, and why?
Also, should we use Route::controller('posts', 'PostController');
or Route::resource('posts', 'PostController');
to pass routing to the controller or should we define each route manually, like below:
Route::get('/users', 'UserController@index');
Route::get('/users/create', 'UserController@create');
Route::post('/users', 'UserController@store');
Route::get('/users/{id}', 'UserController@show');
Route::get('/users{id}/edit', 'UserController@edit');
Route::put('/users', 'UserController@update');
Route::delete('/users', 'UserController@destroy');
Take this controller as example:
<?php
class TestController extends BaseController {
public function getIndex()
{
echo "a";
}
public function postSecond($a)
{
echo "b";
}
}
In your routes, if you have
Route::controller('tests', 'TestController');
And execute
php artisan routes
You'll have:
+--------+--------------------------------------------+------------------------+-----------------------------------+----------------+---------------+
| Domain | URI | Name | Action | Before Filters | After Filters |
+--------+--------------------------------------------+------------------------+-----------------------------------+----------------+---------------+
| | GET /tests/index/{v1}/{v2}/{v3}/{v4}/{v5} | | TestController@getIndex | | |
| | GET /tests | | TestController@getIndex | | |
| | POST /tests | tests.store | TestController@store | | |
| | GET /tests/{_missing} | | TestController@missingMethod | | |
+--------+--------------------------------------------+------------------------+-----------------------------------+----------------+---------------+
Laravel inspects the controller and generates routes based on what methods it finds, automatically.
But if you do
Route::resource('tests', 'TestController');
You'll get this route listing:
+--------+--------------------------------------------+------------------------+-----------------------------------+----------------+---------------+
| Domain | URI | Name | Action | Before Filters | After Filters |
+--------+--------------------------------------------+------------------------+-----------------------------------+----------------+---------------+
| | GET /tests | | Closure | | |
| | GET /tests | tests.index | TestController@index | | |
| | GET /tests/create | tests.create | TestController@create | | |
| | POST /tests | tests.store | TestController@store | | |
| | GET /tests/{tests} | tests.show | TestController@show | | |
| | GET /tests/{tests}/edit | tests.edit | TestController@edit | | |
| | PUT /tests/{tests} | tests.update | TestController@update | | |
| | PATCH /tests/{tests} | | TestController@update | | |
| | DELETE /tests/{tests} | tests.destroy | TestController@destroy | | |
+--------+--------------------------------------------+------------------------+-----------------------------------+----------------+---------------+
No guessing, Laravel uses a predefined CRUD list of routes, you can remove some of those routes but it won't inspect your controller to build routes for your methods.
You decide what's best for you. But, usually, if your controller is a CRUD one, Route::resource() is a good start, otherwhise you can use Route::controller() or build your routes manually.
EDIT:
There no really why one or why another, is just a matter of design and choice. Some will use none of them, ever. It's just hat Route::resource()
follows the Rails way of routing: http://guides.rubyonrails.org/routing.html.
Using Route::resource()
you don't need to create all those methods, but you'll end up with a list of pointless routes, because Laravel always create all of them by default, unless you do:
Route::resource('photo', 'PhotoController',
array('only' => array('index', 'show')));
And your list of routes will show only the index and show actions.
Also, if you need some other routes, using Route::resource()
you'll have to build them manually or work some magic to make them automatic for all your resourceful routes. Using Route::controller()
everything is automatic, everytime you add a new method, a new route is created for you.
Again, if you have a CRUD controller to build, start by using Route::resource()
. Otherwise, think about the benefits of one or another in your particular case.
EDIT2:
This is a great article, from Phil Sturgeon (PyroCMS and PHP-FIG), about the benefits of manually build all your routes: http://philsturgeon.co.uk/blog/2013/07/beware-the-route-to-evil.
@Antonio's answer is good. Let me say something similar and important a little more concisely. In routes.php:
Route::resource('users', 'UserController');
Using the resource method makes Laravel assume CRUD functionality and it only looks for its six, pre-made CRUD methods: index, create, store, show, destroy, etc. It won't "see" any other, new methods you create there.
Route::controller('info', 'InfoController');
Using the controller method allows you to create custom methods/pages. Laravel looks for them when you prepend the method/page name with a HTTP verb. In your XxxxController.php:
class InfoController extends \BaseController {
public function getFeatures()
{
return View::make('info.features');
}
public function getContactUs()
{
return View::make('info.contact-us');
}
public function getPricing()
{
return View::make('info.pricing');
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With