0

Manejando las rutas y URLs en CodeIgniter 4

CodeIgniter 4, como framework moderno que es, ha desarrollado un completo sistema para manejar las rutas, algo que ya lleva tiempo en otros framework como lo son Laravel o Django, en el cual tenemos una capa o nivel adicional para manejar las rutas, por lo tanto, tenemos un mecanismo para indicar que función del controlador va a procesar que URL mediante las rutas.

Composición de las rutas

Al igual que ocurre en la mayoría de los frameworks que trabajan con la capa de ruteo, básicamente definen 3 parámetros básicos:

  1. La URI
  2. El controlador
  3. La función dentro del controlador, que es la que se va a encargar de hacer el proceso

Además del tipo de ruta que lo hablamos un poco más abajo que para este ejemplo es de tipo post:

$routes->post('/save_form', 'Admin::save');

Tipo de rutas

En Codeigniter 4, tenemos múltiples tipos de rutas que podemos emplear según el método a emplear, es decir, si empleamos rutas de tipo get, significa un solamente van a poder resolver las peticiones de tipo, get, ahora si nos interesa enviar un post, que generalmente lo empleamos para por ejemplo, guardar datos desde un formulario, tenemos que crear una ruta de tipo post:

$routes->post('/save_form', 'Admin::save');

Por lo tanto, si intentamos acceder a esta ruta de tipo post mediante una consulta desde el navegador, nos va a dar el siguiente error:

Simplemente un 404 porque estamos accediendo mediante una petición de tipo get a un método que solamente está configurado para ser accedido vía post.

Así que, tenemos que definir otra ruta como get, o simplemente agregamos otra ruta para el get:

$routes->get('/save_form', 'Admin::save'); $routes->post('/save_form', 'Admin::save');

Y con esto, para la siguiente función:

public function save(){
    return "save";
}

Tenemos el resultado esperado:

Porque la ruta anterior funciona para ser consumida tanto por get como por post.

Por supuesto, tenemos también para los de tipo put, patch o delete:

$routes->get('products', 'Product::feature'); 
$routes->post('products', 'Product::feature'); 
$routes->put('products/(:num)', 'Product::feature');
$routes->patch('products/(:num)', 'Product::feature'); 
$routes->delete('products/(:num)', 'Product::feature');

Que las podemos emplear dependiendo del tipo de operación que queramos realizar.

Agrupar rutas

En caso de que tengamos varias rutas con parte de la misma URI igual; por ejemplo supongamos un ahora diremos que nuestra ruta de tenga la palabra admin en la misma:

$routes->group('admin', function ($routes) {
   $routes->get('save_form', 'Admin::save');
   $routes->post('save_form', 'Admin::save');
});

Ahora tenemos que agregar un admin al path; en mi caso:

http://testcodeigniter4.test/admin/save_form 

Puedes agregar tantos niveles de agrupación como quieras o necesites:

$routes->group('admin', function ($routes) {
   $routes->group('user', function ($routes) {
      $routes->get('save_form', 'Admin::save');
      $routes->post('save_form', 'Admin::save');
   });
});

Y para accederla:

http://testcodeigniter4.test/admin/user/save_form

Y queremos crear otra ruta:

$routes->group('admin', function ($routes) {
    $routes->group('user', function ($routes) {
        $routes->get('save_form', 'Admin::save');
        $routes->post('save_form', 'Admin::save'); 
        $routes->get('index', 'Admin::index');    
    });
 });

Perfectamente podemos hacerlo:

http://testcodeigniter4.test/admin/user/index

Y con la siguiente función en nuestro controlador:

public function index(){
        return "Admin";
}

Tenemos lo siguiente:

Parámetros paras las rutas y ulrs

También podemos definir parámetros a las rutas para pasar datos adicionales; por ejemplo un número:

$routes->get('save_form/(:num)', 'Admin::save/$1', ['as' => 'admin_save']);

Desde la función:

public function save($id){
        return "save: ".$id;
}

Placeholders

Podemos configurar distintos placeholders según el tipo de dato que queremos recibir:

PlaceholdersDescripción
(:any)Hará match con cualquier carácter que le pasemos por la URL.
(:segment)Igual que el anterior excluyendo el /.
(:num)Match con cualquier entero.
(:alpha)Match con cualquier carácter del alfabeto.
(:alphanum)Match con cualquier carácter del alfabeto o número.
(:hash) 

Rutas con nombre

Nosotros también podemos darle un nombre a nuestra ruta, más adelante, en otra entrada veremos un ejemplo práctico de todo esto, pero suponte que simplemente es una referencia que nosotros le damos para poder referencias a la ruta mediante el nombre y NO directamente colocar la URI; la ventaja de esto se explica por sí sola y de esta manera nosotros podemos variar perfectamente la URI sin necesidad de actualizar la referencia en nuestro código:

$routes->get('save_form', 'Admin::save', ['as' => 'admin_save']);

Y desde una vista; simplemente colocamos la referencia al nombre:

<?= route_to('admin_save') ?>

Si recibiera argumentos:

<?= route_to('admin_save', $movie->id) ?>

Definir nuestras rutas para una operación tipo CRUD

Lo más usual en los sistemas es que necesitemos realizar operaciones tipo CRUD, es decir, para crear, leer, actualizar y eliminar alguna entidad, como puedes ver, por ejemplo para la vista de crear y actualizar necesitamos definir dos rutas post cada una de estas operaciones, una para mostrar el formulario y otra para procesar la información más la vista para el listado serian un total de 7 rutas diferentes para hacer una operación genérica como hacer un CRUD; por suerte framework modernos como lo son CodeIgniter 4, contamos con un método que nos permite definir mediante una sola función o método todos los tipos de rutas que necesitemos:

$routes->resource('photos', $options);

Puedes ver las rutas que les tenemos que especificar en la documentación oficial.

Rutas comunes

En C4, podemos decir que las rutas comunes a utilizar en cualquier aplicación son:

$routes->get('pelicula','Pelicula::index'); // De tipo get para generar un listado de elementos

$routes->get('pelicula/new','Pelicula::new'); // De tipo get para pintar el formulario de creación

$routes->post('pelicula','Pelicula::create');// De tipo create para procesar el formulario al momento de crear un recurso

$routes->get('pelicula/xx/edit','Pelicula::edit');// De tipo get para pintar el formulario para editar un elemento

$routes->put('pelicula/xx','Pelicula::update');// de tipo put para procesar todo el formulario de un registro existente

$routes->delete('pelicula/xx','Pelicula::delete'); // de tipo delete que como sorpresa, permite eliminar un registro

El anterior esquema son las URIs usadas por excelencia para realizar cada una de las operaciones señaladas y los tipos de rutas comunes para realizar los famosos CRUD a nivel de la aplicación.

Ver las rutas generadas

Para poder ver las rutas generadas a nivel de la aplicación, tenemos el comando de spark:

php spark routes

Generar rutas de manera automática

Una característica muy interesante que tiene CodeIgniter, es la de poder generar rutas de manera automática, segun los métodos que tengamos registrados, para esto, en nuestro archivo de rutas, tenemos que habilitarlo:

$routes->setAutoRoute(true);

Dado el siguiente controlador:

<?php
namespace App\Controllers;

class Pelicula extends BaseController {

    public function index()
    {
        echo "Hola Mundo";
    }
    public function test($x = 0,$n = 10)
    {
        echo "Hola Mundo test ".$x." ".$n;
    }

    // public function new()
    // {
    //    echo view("pelicula/create");
    // }

    // public function create()
    // {
    //     echo "Procesando el Form!";
    // }
    public function edit($id)
    {
       echo view("pelicula/edit");
    }

    public function update($id)
    {
        echo "Procesando el Form! ".$id;
    }

}

Y remueves las rutas anteriormente definidas y revisas que rutas han sido generadas:

 Method | Route                 | Handler                                  |
+--------+-----------------------+------------------------------------------+
| auto   | /                     | \App\Controllers\Home::index             |
| auto   | home                  | \App\Controllers\Home::index             |
| auto   | home/index[/...]      | \App\Controllers\Home::index             |
| auto   | pelicula              | \App\Controllers\Pelicula::index         |
| auto   | pelicula/index[/...]  | \App\Controllers\Pelicula::index         |
| auto   | pelicula/test[/...]   | \App\Controllers\Pelicula::test          |
| auto   | pelicula/edit[/...]   | \App\Controllers\Pelicula::edit          |
| auto   | pelicula/update[/...] | \App\Controllers\Pelicula::update        |
+--------+-----------------------+------------------------------------

Es una opción particularmente útil cuando tienes una aplicación en la cual puedas aprovechar este tipo de característica.

Deja una respuesta

Your email address will not be published. Required fields are marked *