RESTful Resource Handling

Representational State Transfer (REST) is an architectural style fordistributed applications, first described by Roy Fielding in his2000 PhD dissertation, Architectural Styles andthe Design of Network-based Software Architectures.That might be a bit of a dry read, and you might find Martin Fowler’sRichardson Maturity Modela gentler introduction.

REST has been interpreted, and mis-interpreted, in more ways than mostsoftware architectures, and it might be easier to say that the moreof Roy Fielding’s principles that you embrace in an architecture, themost “RESTful” your application would be considered.

CodeIgniter makes it easy to create RESTful APIs for your resources,with its resource routes and ResourceController.

Resource Routes

You can quickly create a handful of RESTful routes for a single resource with the resource() method. Thiscreates the five most common routes needed for full CRUD of a resource: create a new resource, update an existing one,list all of that resource, show a single resource, and delete a single resource. The first parameter is the resourcename:

  1. $routes->resource('photos');
  2.  
  3. // Equivalent to the following:
  4. $routes->get('photos/new', 'Photos::new');
  5. $routes->post('photos', 'Photos::create');
  6. $routes->get('photos', 'Photos::index');
  7. $routes->get('photos/(:segment)', 'Photos::show/$1');
  8. $routes->get('photos/(:segment)/edit', 'Photos::edit/$1');
  9. $routes->put('photos/(:segment)', 'Photos::update/$1');
  10. $routes->patch('photos/(:segment)', 'Photos::update/$1');
  11. $routes->delete('photos/(:segment)', 'Photos::delete/$1');

Note

The ordering above is for clarity, whereas the actual order the routes are created in, in RouteCollection, ensures proper route resolution

Important

The routes are matched in the order they are specified, so if you have a resource photos above a get ‘photos/poll’ the show action’s route for the resource line will be matched before the get line. To fix this, move the get line above the resource line so that it is matched first.

The second parameter accepts an array of options that can be used to modify the routes that are generated. While theseroutes are geared toward API-usage, where more methods are allowed, you can pass in the ‘websafe’ option to have itgenerate update and delete methods that work with HTML forms:

  1. $routes->resource('photos', ['websafe' => 1]);
  2.  
  3. // The following equivalent routes are created:
  4. $routes->post('photos/(:segment)/delete', 'Photos::delete/$1');
  5. $routes->post('photos/(:segment)', 'Photos::update/$1');

Change the Controller Used

You can specify the controller that should be used by passing in the controller option with the name ofthe controller that should be used:

  1. $routes->resource('photos', ['controller' =>'App\Gallery']);
  2.  
  3. // Would create routes like:
  4. $routes->get('photos', 'App\Gallery::index');

Change the Placeholder Used

By default, the segment placeholder is used when a resource ID is needed. You can change this by passingin the placeholder option with the new string to use:

  1. $routes->resource('photos', ['placeholder' => '(:id)']);
  2.  
  3. // Generates routes like:
  4. $routes->get('photos/(:id)', 'Photos::show/$1');

Limit the Routes Made

You can restrict the routes generated with the only option. This should be an array or comma separated list of method names that shouldbe created. Only routes that match one of these methods will be created. The rest will be ignored:

  1. $routes->resource('photos', ['only' => ['index', 'show']]);

Otherwise you can remove unused routes with the except option. This option run after only:

  1. $routes->resource('photos', ['except' => 'new,edit']);

Valid methods are: index, show, create, update, new, edit and delete.

ResourceController

The ResourceController provides a convenient starting point for your RESTful API,with methods that correspond to the resource routes above.

Extend it, over-riding the modelName and format properties, and thenimplement those methods that you want handled.:

  1. <?php namespace App\Controllers;
  2.  
  3. use CodeIgniter\RESTful\ResourceController;
  4.  
  5. class Photos extends ResourceController
  6. {
  7.  
  8. protected $modelName = 'App\Models\Photos';
  9. protected $format = 'json';
  10.  
  11. public function index()
  12. {
  13. return $this->respond($this->model->findAll());
  14. }
  15.  
  16. // ...
  17. }

The routing for this would be:

  1. $routes->resource('photos');

Presenter Routes

You can quickly create a presentation controller which alignswith a resource controller, using the presenter() method. Thiscreates routes for the controller methods that would return viewsfor your resource, or process forms submitted from those views.

It is not needed, since the presentation can be handled witha conventional controller - it is a convenience.Its usage is similar to the resource routing:

  1. $routes->presenter('photos');
  2.  
  3. // Equivalent to the following:
  4. $routes->get('photos/new', 'Photos::new');
  5. $routes->post('photos/create', 'Photos::create');
  6. $routes->post('photos', 'Photos::create'); // alias
  7. $routes->get('photos', 'Photos::index');
  8. $routes->get('photos/show/(:segment)', 'Photos::show/$1');
  9. $routes->get('photos/(:segment)', 'Photos::show/$1'); // alias
  10. $routes->get('photos/edit/(:segment)', 'Photos::edit/$1');
  11. $routes->post('photos/update/(:segment)', 'Photos::update/$1');
  12. $routes->get('photos/remove/(:segment)', 'Photos::remove/$1');
  13. $routes->post('photos/delete/(:segment)', 'Photos::update/$1');

Note

The ordering above is for clarity, whereas the actual order the routes are created in, in RouteCollection, ensures proper route resolution

You would not have routes for photos for both a resource and a presentercontroller. You need to distinguish them, for instance:

  1. $routes->resource('api/photo');
  2. $routes->presenter('admin/photos');

The second parameter accepts an array of options that can be used to modify the routes that are generated.

Change the Controller Used

You can specify the controller that should be used by passing in the controller option with the name ofthe controller that should be used:

  1. $routes->presenter('photos', ['controller' =>'App\Gallery']);
  2.  
  3. // Would create routes like:
  4. $routes->get('photos', 'App\Gallery::index');

Change the Placeholder Used

By default, the segment placeholder is used when a resource ID is needed. You can change this by passingin the placeholder option with the new string to use:

  1. $routes->presenter('photos', ['placeholder' => '(:id)']);
  2.  
  3. // Generates routes like:
  4. $routes->get('photos/(:id)', 'Photos::show/$1');

Limit the Routes Made

You can restrict the routes generated with the only option. This should be an array or comma separated list of method names that shouldbe created. Only routes that match one of these methods will be created. The rest will be ignored:

  1. $routes->presenter('photos', ['only' => ['index', 'show']]);

Otherwise you can remove unused routes with the except option. This option run after only:

  1. $routes->presenter('photos', ['except' => 'new,edit']);

Valid methods are: index, show, new, create, edit, update, remove and delete.

ResourcePresenter

The ResourcePresenter provides a convenient starting point for presenting viewsof your resource, and processing data from forms in those views,with methods that align to the resource routes above.

Extend it, over-riding the modelName property, and thenimplement those methods that you want handled.:

  1. <?php namespace App\Controllers;
  2.  
  3. use CodeIgniter\RESTful\ResourcePresenter;
  4.  
  5. class Photos extends ResourcePresenter
  6. {
  7.  
  8. protected $modelName = 'App\Models\Photos';
  9.  
  10. public function index()
  11. {
  12. return view('templates/list',$this->model->findAll());
  13. }
  14.  
  15. // ...
  16. }

The routing for this would be:

  1. $routes->presenter('photos');

Presenter/Controller Comparison

This table presents a comparison of the default routes created by resource()_and _presenter() with their corresponding Controller functions.

OperationMethodController RoutePresenter RouteController FunctionPresenter Function
NewGETphotos/newphotos/newnew()new()
CreatePOSTphotosphotoscreate()create()
Create (alias)POST photos/create create()
ListGETphotosphotosindex()index()
ShowGETphotos/(:segment)photos/(:segment)show($id = null)show($id = null)
Show (alias)GET photos/show/(:segment) show($id = null)
EditGETphotos/(:segment)/editphotos/edit/(:segment)edit($id = null)edit($id = null)
UpdatePUT/PATCHphotos/(:segment) update($id = null)
Update (websafe)POSTphotos/(:segment)photos/update/(:segment)update($id = null)update($id = null)
RemoveGET photos/remove/(:segment) remove($id = null)
DeleteDELETEphotos/(:segment) delete($id = null)
Delete (websafe)POST photos/delete/(:segment)delete($id = null)delete($id = null)