Slim, mini framework REST para PHP

Slim PHP

Si necesitamos crear el backend para algún proyecto sencillo en PHP, quizás no necesitemos un gran framework con miles de opciones como CodeIgniter o Laravel. Pero quizás tampoco convenga escribir el sistema de cero, para no reinventar la rueda.

A mitad de camino se encuentra Slim, un micro framework PHP para crear aplicaciones REST con una sintaxis muy simple. Desde el router asociamos cierta pedido HTTP con funciones anónimas, de esta manera:

// Instanciamos nuestra aplicación
$app = new \Slim\Slim();

// Asociamos una URL a una función deduciendo el parámetro name
$app->get('/hello/:name', function ($name) {
    echo "Hello, $name";
});

// Ponemos en marcha el router
$app->run();

Al ingresar en /hello/world se ejecutará la función y entonces veremos en pantalla el mensaje.

A continuación, vamos a repasar cómo instalar Slim, trabajar con parámetros de URL, probar su sistema de templates y construir un sencillo API REST.

Instalación

Para comenzar a trabajar con Slim puede clonar el repositorio de GitHub o bien descargar su última versión. Una vez que lo tengan pueden ubicar la carpeta Slim en la raíz de su proyecto, donde también estará nuestro archivo index.php que será el router principal.

Desde ese archivo, incluímos Slim:

require 'Slim/Slim.php';
\Slim\Slim::registerAutoloader();

Vemos que Slim sigue las convenciones de PSR-0: noten el uso del namespace Slim en la primer línea y en la segunda, la llamada a una clase que maneja el autoloading de dependencias. No importa si no saben de qué estamos hablando, pronto repasaremos ese standard en futuros posts.

Perfecto, ya tenemos todo listo para usar. Entonces, creamos una instancia llamada $app:

$app = new \Slim\Slim();

Bien, vamos a crear nuestra primer ruta. Será hacia una página estática, por ejemplo, about.

$app->get('/about/', function () {
    echo "About Us";
});

Y ponemos en marcha el router:

$app->run();

No olviden incluir esa última línea porque si no la aplicación no va a funcionar, no va a escuchar los pedidos ni conectarlos con sus funciones.

Nuestras URL con Slim quedan mucho más legibles, tanto por el usuario como por nuestro amigo Google Bot. En lugar de /about.php, ya tenemos /about.

Parámetros de URL

Hemos visto páginas estáticas pero, ¿qué sucede con las páginas dinámicas?

La URL del detalle de un producto puede ser /products/?id=85, recibiendo los parámetros por $_GET como siempre lo hacemos en PHP:


$app->get('/products/', function () {
echo "Show product" . $_GET['id'];
});

Pero aún mejor sería contar con una URL como /products/85, donde cualquier número que esté después de la última barra sea reconocido como id. Con Slim podemos hacerlo así:

$app->get('/products/:id', function ($id) {
    echo "Show details for product" . $id;
});

Como ven, incluímos en la URL el nombre de la variable que vamos a capturar con dos puntos por delante, por ejemplo :id, y lo recibimos como parámetro en nuestra función. El resultado es el mismo que antes, pero la URL es mucho más limpia y amigable.

Parámetros opcionales

También podemos hacer que el parámetro sea opcional al encerrarlo entre paréntesis. En el siguiente ejemplo, mostramos el detalle de un producto o el listado, según hayamos recibido o no un id:

$app->get('/products/(:id)', function ($id) {
    if ($id) {
        echo "Show details for product" . $id;      
    } else {
        echo "Show products list";
    }
});

Ahora, imaginen que tenemos un blog y necesitamos mostrar el archivo por año, mes o día. Necesitamos una ruta que resuelva todas estas URL:

  • article
  • article/2013
  • article/2013/05/
  • article/2013/05/12

Para eso, podemos podemos incluir opcionales dentro de opcionales, y hacer algo como:

$app->get('/archive(/:year(/:month(/:day)))', function ($year = 2013, $month = 1, $day = 1) {
    echo "$year, $month, $day";
});

Observen que definimos también valores por defecto de los parámetros, como en cualquier función, por si no llegan definidos.

Ahora supongan que en nuestro blog tenemos paginado, por lo que necesitamos URLs como:

  • /page/2/
  • /page/3/

Y también tags, que usan URLs como:

  • /tag/php/
  • /tag/javascript/

Y sumar ambas posibilidades. Por ejemplo, la segunda página del listado de post de javascript sería:

  • /tag/javascript/page/2/

Entonces necesitamos one route to rule them all. Que pueda recibir un parámetro, ambos o ninguno, pero igual pueda resolver. Para este caso podemos crear diversos conjuntos de parámetros opcionales, de esta forma:

$app->get('(/tag/:tag)(/page/:page)(/)', function ($tag = false, $page = 1) {
    echo "$tag, $page";
});

Como ven, cada una de las partes es opcional: tag, page y la barra del final. Porque entre paréntesis podemos poner cualquier parte de la URL, no necesariamente un parámetro.

Templates

Por supuesto, es raro que nuestra funciones utilicen simples echo para mostrar el contenido. Lo más probable sea que tengamos cierta template, por ejemplo templates/product.php, que tome todas las variables del producto y las muestre en HTML.

Para esto, el método render de Slim nos permite renderizar una template con ciertos datos. Para utilizarlo, primero creamos la carpeta templates en la raíz de nuestros proyecto. Guardamos ahí products.php:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Online Shop</title>
    </head>
    <body>
        <p>Product: <?=$name?></p>
        <p>Price:

lt;?=$price?></p>
</body>
</html>
Y agregamos render a la función que muestra el producto:

$app->get('/products/:id', function ($id) use ($app) {
    // Llamamos al metodo render
    $app->render(
        // El primer parametro es la template a utilizar
        'products.php', 
        // El segundo es opcional, son los datos que queremos que tome
        array('name' => 'Converse All Star', 'price' => 30)
    );
});

Noten que decimos use $app, para poder hacer uso de esa instancia en nuestro callback. Si queremos utilizar otra carpeta que no sea la definida por defecto, podemos hacerlo cambiando la configuración al instanciar la aplicación. Por ejemplo:

$app = new \Slim\Slim(array(
    'templates.path' => './includes/views'
));

REST

Nuestras rutas por ahora han sido todas de tipo GET. Pero, ¿qué pasa si, por ejemplo, quiero recibir un formulario de contacto enviado por POST… sobre la misma ruta? Bien, podemos tener algo como:

// GET
$app->get('/contact/', function () use ($app) {
    // Mostamos el formulario de contacto
    $app->render('contact.php');
}); 

// POST
$app->post('/contact/', function () use ($app) {
    // Recibimos el formulario de contacto
    $data = $_POST['form'];
    // Enviamos los datos por mail
    mail('john@example.com', 'Contact from web', implode(',', $data));
    // Redirigimos a otra ruta
    $app->redirect('/contact/thanks');
});

En el ejemplo no hacemos chequeos ni nada complejo, es sólo a fines de mostrar cómo la misma URL para distintos pedidos HTTP (GET y POST en este caso) tiene un callback diferente.

Hasta ahora hablamos de un sitio web, pero Slim también puede ayudarnos a crear un API. Sabiendo que Slim también puede tomar pedidos de tipo PUT y DELETE, crear un API completamente REST está a la vuelta de la esquina:

$app->get('/articles/(:id)', function ($id) {
    // Devuelve una lista de articulos o un articulo en particular
});

$app->post('/articles/', function () {
    // Crea un articulo
});

$app->put('/articles/:id', function ($id) {
    // Modifica un articulo
});

$app->delete('/articles/:id', function ($id) {
    // Borra un artículo
});

Conclusión

Slim es un excelente framework MVC que nos permite crear aplicaciones rápidamente sin levantar una infresctructura llena de módulos y opciones que no vamos a utilizar. Es liviano, la sintaxis es clara y hace uso extensivo de todas las cualidades de PHP 5.3.

Si su sitio web o aplicación necesita controlar muchas rutas muy diferentes y cientos de objetos, conviene inclinarse por otras opciones como Laravel.

Pero si están buscando una solución sencilla o nunca utilizaron un framework pero quieren comenzar, Slim es lo que necesitan. ¡Incluso podemos utilizarlo como backend de una aplicación en Backbone…!

Espero que les haya servido esta guía, hay mucho más para ver sobre Slim, asi que… ¡Nos vemos la próxima!

3 opiniones en “Slim, mini framework REST para PHP”

  1. Excelente post, en el tema de autenticación y login podrías generar un ejemplo, es bastante didáctica tu forma de redactar y creo que ayudaría a la comunidad slim de habla hispana.

    Felicidades por el post.

  2. Puede ser util para hacer servicios PHP donde se devuelve Json? O no se vé diferencia en ese caso?

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *