Práctica: Crear una API con Slim 4
1. Introducción
¿Qué es Slim 4 y sus ventajas?
Slim 4 es un microframework de PHP diseñado para crear aplicaciones web simples y API RESTful. Es muy ligero, flexible y fácil de usar, lo que lo convierte en una excelente opción para crear servicios rápidos y eficientes sin sobrecargar el proyecto con características innecesarias.
Ventajas de Slim 4:
- Ligero: Tiene una base muy pequeña, por lo que el rendimiento es óptimo.
- Flexible: Puedes añadir solo lo que necesitas. Slim es muy configurable.
- Fácil de aprender: Su sintaxis es sencilla y la documentación es clara.
- Ideal para APIs: Slim facilita la creación de APIs RESTful, con soporte integrado para JSON, rutas, middleware, etc.
Requisitos previos
Para comenzar con Slim 4, necesitas tener los siguientes requisitos previos:
- PHP 7.3 o superior.
- Composer para la gestión de dependencias de PHP.
- Docker (opcional) para crear un entorno de desarrollo aislado con PHP, Nginx y MySQL.
- Visual Studio Code (VSCode) o cualquier editor de código de tu preferencia.
2. Instalación de Slim 4
Preparación
Mi recomendación es que crees un nuevo proyecto en github para ir subiendo los avances de la práctica. Le puedes llamar phpSlimApi. Luego clona el proyecto en tu máquina local.
git clone
git clone https://github.com/tu_usuario/phpSlimApi.git
De esta manera jugando con git y las ramas podrás ir guardando los avances de la práctica.
Instalación del entorno de desarrollo
Para el entorno de desarrollo vamos a mantener el que hemos creado para PHP. Recuerda que es un Docker compose con PHP, Nginx y MySQL. Importante antes de comeenar tener todo en funcionamiento y hacer una prueba con documento index.php que contenga la función: phpinfo();.
La estructura de carpetas es la siguiente:
mi_api_slim/
│├── docker-compose.yml
│├── nginx/
││ └── default.conf
│├── php/
││ └── Dockerfile
│├── mysql/
││ └── data/
││ └── tmp/
│├── src/
││ └── index.php
Comprobaciones iniciales
A partir de ahora necesitaremos trabajar con erramientas como composer que no estan instaladas en nuestro equipo, están instaladas en el contenedor php. Por lo tanto, para ejecutar comandos de composer o php deberemos hacerlo a través del contenedor.
Lo primero será entrar en el contenedor php:
docker compose exec php bash
php y composer:
php -v
composer --version
resultado esperado

Si todo está correcto, ya podemos proceder a instalar Slim 4.
Instalación de Slim 4 via Composer
-
Situarnos en docker php: Asegúrate de estar dentro del contenedor
phpcomo se explicó anteriormente. -
Instalar Slim 4: Slim 4 se gestiona mediante Composer, así que ejecuta el siguiente comando para instalarlo:
composer require slim/slimEsto descargará e instalará Slim 4 y sus dependencias. Composer se encargará de gestionar las versiones y dependencias para ti.
Atención
Te aparecerá en el proyecto una nueva carpeta llamada
vendordonde se encuentran todas las librerías instaladas porcomposery un archivocomposer.jsonque contiene la información del proyecto y las dependencias. Es importante no eliminar ni modificar estas carpetas y archivos.Composeres un gestor de paquetes y lo necesita para funcionar correctamente.Si vamos al sitio web de Slim Framework podemos ver la documentación oficial. En la guía de instalación podemos ver que también es necesario instalar
Slim PSR-7para manejar las peticiones y respuestas HTTP:composer require slim/psr7Configuración del servidor web (Nginx)
Ahora es necesario modificar la configuración de Nginx. Ahora composer nos ha creado una serie de carpetas y acrchivos en src a los que NO queremos acceder directamente desde el navegador. Por lo tanto, debemos modificar la configuración de Nginx para que el directorio raíz apunte a src/public.
Además también vamos a crear dentro de src una carpeta logs donde Nginx guardará los logs de acceso y errores (nos pueden ser útilies para depurar errores).
Ahora modificamos el contenido del archivo nginx/default.conf para que quede de la siguiente manera:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
nginx para que los cambios tengan efecto:
docker compose restart nginx
Esta configuración la puedes encontrar en la documentación oficial de Slim 4 en el apartado de Nginx Configuration. Aunque se ha modificado la última línea para que acceda al contenedor php que es donde tenemos instalado php-fpm, y el puerto 9000 que es el que utiliza php-fpm por defecto.
Otro cambio importante es la línea root /var/www/html/public; que indica que el directorio raíz es public dentro de src. Ahora debemos crear esa carpeta public dentro de src y mover el archivo index.php que tenemos en src a src/public.
Configuración básica de Slim 4
-
Crear el archivo de inicio: Crea un archivo
index.phpdentro desrc/public. Este será el punto de entrada de tu aplicación Slim.index.php 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
<?php require 'vendor/autoload.php'; // Crear la aplicación Slim $app = \Slim\Factory\AppFactory::create(); // Definir una ruta básica $app->get('/', function ($request, $response, $args) { $response->getBody()->write("<p>¡Hola, mundo!</p>"); return $response; }); // Ejecutar la aplicación $app->run(); -
Comprobar funcionamiento:
Esto hará que el servidor se ejecute en
http://localhost:8080. Abre tu navegador y visita esa URL para ver el mensaje "¡Hola, mundo!" que definimos en la ruta.URL
Fíjate que una vez instalado el
FRAMEWORKla URL ha cambiado. Ahora eshttp://localhost:8080, ahora no hay que indicar la páginaindex.phpya queSlimse encarga de gestionar las rutas. Si intentas acceder ahttp://localhost:8080/index.phpte dará error ya que no existe esa ruta.
3. Creación de la Base de Datos
Configuración de la Base de Datos MySQL
-
Crear la base de datos: Usando MySQL o MariaDB, crea una base de datos para la API. Por ejemplo, en MySQL:
CREATE DATABASE mi_api; -
Crear una tabla de usuarios: Crea una tabla para almacenar usuarios. Aquí tienes un ejemplo de cómo crearla:
CREATE TABLE usuarios ( id INT AUTO_INCREMENT PRIMARY KEY, nombre VARCHAR(100) NOT NULL, email VARCHAR(100) NOT NULL UNIQUE, creado_en TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
Conexión a la base de datos desde Slim
-
Crear una clase para la conexión a la base de datos: Crea un archivo
db.phpque contendrá la lógica de conexión con la base de datos:db.php 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
<?php use PDO; class Database { private $host = 'mysql'; private $db = 'mi_api'; private $user = 'alumno'; // Cambia con tu usuario de MySQL private $pass = 'alumno'; // Cambia con tu contraseña de MySQL private $charset = 'utf8mb4'; public $pdo = null; public function connect() { if ($this->pdo === null) { $dsn = "mysql:host=$this->host;dbname=$this->db;charset=$this->charset"; try { $this->pdo = new PDO($dsn, $this->user, $this->pass); $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); echo "<p>Connected to the database successfully!</p>"; } catch (PDOException $e) { echo "<p>Connection failed: " . $e->getMessage() . "</p>"; } } return $this->pdo; } }Ahora llamaremos a este archivo desde
index.phppara establecer la conexión y comprobar que funciona. Hacerlo antes de crear la aplicación ya que las rutas las crearemos después y necesitaremos la conexión a la base de datos.```phprequire 'db.php';
$db = new Database(); $pdo = $db->connect(); ```
-
Usar la conexión en la API: En el archivo
index.php, añade el código para conectar la base de datos:require 'db.php'; $db = new Database(); $pdo = $db->connect();Volvemos a cargar la página en el navegador y si todo está correcto veremos el mensaje de conexión exitosa a la base de datos.
Conexión exitosa
Si ves el mensaje de conexión exitosa, ya puedes proceder a crear las rutas de la API para gestionar los usuarios.

4. Creación de Rutas de la API
Para no tener todo el código en un solo archivo, vamos a crear un nuevo archivo llamado routes.php en una carpeta llamada 'routes/'donde definiremos todas las rutas de la API. Luego incluiremos este archivo en index.php.
Creamos el fichero y añadimos este código para probar que funciona:
| routes.php | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 | |
ahora en index.php incluimos el archivo routes.php justo después de crear la aplicación y antes de ejecutar la aplicación:
| index.php | |
|---|---|
1 2 3 4 5 | |
http://localhost:8080/userarios
y veremos el mensaje "Users list". Si es así todo está correcto y podemos proceder a crear las rutas RESTful para gestionar usuarios.
Crear las rutas RESTful para gestionar usuarios
Primero hay una parte de conexión a la base de datos para obtener la información de los usuarios. Luego construimos en $data un array con el número total de usuarios y los datos de los usuarios. Finalmente, codificamos el resultado en JSON y lo devolvemos en la respuesta.
-
Ruta GET para obtener todos los usuarios:
GET /usuarios 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
$app->get('/usuarios', function ($request, $response, $args) use ($pdo) { // Realizamos la consulta para obtener los usuarios $stmt = $pdo->query("SELECT * FROM usuarios"); $usuarios = $stmt->fetchAll(PDO::FETCH_ASSOC); // Creamos un array con los usuarios y el número total de usuarios $data = [ 'total' => count($usuarios), // Contamos el número de usuarios 'usuarios' => $usuarios // Los datos de los usuarios ]; // Codificamos el resultado en JSON $response->getBody()->write(json_encode($data)); // Establecemos el header Content-Type a application/json return $response->withHeader('Content-Type', 'application/json'); });Aunque al ser un GET podemos seguir utiliando el navegador para probar la ruta, es mejor usar una herramienta como
PostmanoREST ClientenVSCodeque veremos más adelante.Respuesta JSON
La respuesta de esta ruta será un JSON con la lista de usuarios y el número total de usuarios. Por ejemplo:

En este caso hay 0 usuarios, pero si damos de alta usuarios veremos los datos en el JSON.
-
Ruta POST para crear un nuevo usuario:
A diferencia de una ruta GET, para crear un nuevo usuario necesitamos pasar información al servidor (nombre y email por ejemplo). Por lo tanto, usaremos una ruta POST que recibirá los datos en el cuerpo de la petición. Luego veremos como pasar esta información usando
REST ClientenVSCode.Validaciones
En este ejemplo no se incluyen validaciones de datos. En un entorno real, es importante validar los datos recibidos para evitar errores y problemas de seguridad. Las veremos más adelante.
POST /usuarios 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
$app->post('/usuarios', function ($request, $response, $args) use ($pdo) { //$data = $request->getParsedBody(); $data = json_decode($request->getBody(), true); $nombre = $data['nombre']; $email = $data['email']; $stmt = $pdo->prepare("INSERT INTO usuarios (nombre, email) VALUES (?, ?)"); $stmt->execute([$nombre, $email]); $output = [ 'id' => $pdo->lastInsertId(), 'nombre' => $nombre, 'email' => $email, ]; $response->getBody()->write(json_encode($output)); return $response->withHeader('Content-Type', 'application/json'); });Un ejemplo de petición POST para crear un usuario sería:
POST http://localhost:8080/usuarios Content-Type: application/json { "nombre": "Juan Pérez", "email": "juan.perez@example.com" }Respuesta
La respuesta de esta ruta será un mensaje indicando que el usuario ha sido creado correctamente.

-
Ruta PUT para actualizar un usuario:
PUT /usuarios/{id} 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
$app->put('/usuarios/{id}', function ($request, $response, $args) use ($pdo) { $id = $args['id']; $data= json_decode($request->getBody(), true); $nombre = $data['nombre']; $email = $data['email']; $stmt = $pdo->prepare("UPDATE usuarios SET nombre = ?, email = ? WHERE id = ?"); $stmt->execute([$nombre, $email, $id]); $output = [ 'id' => $id, 'nombre' => $nombre, 'email' => $email, 'mensaje' => 'Usuario actualizado correctamente' ]; $response->getBody()->write(json_encode($output)); return $response->withHeader('Content-Type', 'application/json'); });La petición PUT para actualizar un usuario sería:
PUT http://localhost:8080/usuarios/1 Content-Type: application/json { "nombre": "Juan Pérez Actualizado", "email": "juan.perez.actualizado@example.com" }Respuesta
La respuesta de esta ruta será un mensaje indicando que el usuario ha sido actualizado correctamente.

-
Ruta DELETE para eliminar un usuario:
DELETE /usuarios/{id} 1 2 3 4 5 6 7 8 9 10 11 12 13 14
$app->delete('/usuarios/{id}', function ($request, $response, $args) use ($pdo) { $id = $args['id']; $stmt = $pdo->prepare("DELETE FROM usuarios WHERE id = ?"); $stmt->execute([$id]); $output = [ 'id' => $id, 'mensaje' => 'Usuario eliminado correctamente' ]; $response->getBody()->write(json_encode($output)); return $response->withHeader('Content-Type', 'application/json'); });Para eliminar un usuario, la petición DELETE sería:
DELETE http://localhost:8080/usuarios/1Respuesta
La respuesta de esta ruta será un mensaje indicando que el usuario ha sido eliminado correctamente.

5. Acceso a las Rutas con REST Client
Ya lo hemos visto en el punto anterior en las pruebas de las rutas, pero vamos a verlo con más detalle.
Usar REST Client en Visual Studio Code
- Instalar la extensión REST Client en VSCode desde el marketplace de extensiones.
-
Realizar peticiones a la API: Crea un archivo de texto con extensión
.httpo.resty agrega las siguientes peticiones: -
GET para obtener usuarios:
GET http://localhost:8080/usuarios -
POST para crear un usuario:
POST http://localhost:8080/usuarios Content-Type: application/json { "nombre": "Carlos Gómez", "email": "carlos@example.com" } -
PUT para actualizar un usuario:
PUT http://localhost:8080/usuarios/1 Content-Type: application/json { "nombre": "Carlos Gómez Actualizado", "email": "carlos_actualizado@example.com" } -
DELETE para eliminar un usuario:
DELETE http://localhost:8080/usuarios/1
Ver las respuestas
Cuando estamos ofreciendo un servicio RESTful, las respuestas deben ser en formato JSON. En REST Client, al hacer clic en "Send Request", la respuesta se mostrará en una nueva pestaña con el formato adecuado. Es importante dar informacion suficiente en las respuestas para que el cliente pueda entender el resultado de la operación.
6. Validación de Datos y Seguridad
Validación Básica de Datos
En este punto, se explica cómo realizar una validación simple para asegurarse de que los datos ingresados por el usuario sean correctos antes de ser procesados o almacenados en la base de datos.
Ejemplo de Validación en la Ruta POST para Crear un Usuario
Vemoa un ejemplo de validación básica en la ruta POST para crear un usuario, luego podemos aplicar validaciones similares en las otras rutas.
En la ruta de POST /usuarios, validamos que el nombre y el correo sean proporcionados y que el correo tenga un formato válido:
| POST /usuarios con validación | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | |
Es importante fijarse además de los mensajes de error, los códigos de estado HTTP que se devuelven en cada caso. Esto ayuda al cliente a entender el resultado de la operación.
| Código | Significado |
|---|---|
| 200 | OK |
| 201 | Created (Recurso creado) |
| 400 | Bad Request (Solicitud incorrecta) |
| 404 | Not Found (No encontrado) |
| 500 | Internal Server Error (Error interno del servidor) |
Es común usar estos códigos para indicar el resultado de las operaciones en una API RESTful.
Seguridad Básica
La seguridad básica puede incluir la autenticación y la validación de datos. Aquí te muestro un ejemplo de cómo usar un middleware para proteger las rutas.
Middleware para Autenticación Básica
Este punto lo dejamos de momento para más adelante, para no alargar más el tema y por su complejidad, ahora estamos intentando asimilar el funcionamiento básico de Slim 4.
Solo adelantar que para algunas funciones añadidas los frameworks suelen utilizar middleware que son funciones que se ejecutan antes de que una petición llegue al su controlador (o manejador de ruta). Un ejemplo común es un middleware de autenticación que verifica si el usuario está autenticado antes de permitirle acceder a ciertas rutas.
Tanto Slim 4 como otros frameworks como Laravelpermiten crear y usar middleware de manera sencilla.
Aquí os dejo un par de enlaces para que podáis investigar más sobre este tema:
7. Conclusión y Próximos Pasos
Resumen
En esta práctica, hemos aprendido a crear una API básica usando Slim 4, cubriendo los aspectos fundamentales como la configuración, la creación de rutas RESTful, la conexión con una base de datos MySQL y la validación de datos. También hemos explorado cómo realizar pruebas con REST Client y cómo hacer configuraciones básicas de seguridad.
Ampliaciones
- Autenticación y autorización: Implementa autenticación basada en JWT para proteger tus rutas.
- Control de errores avanzado: Usa un sistema de manejo de errores centralizado para responder de manera adecuada a los problemas.
- Paginación y filtros: Añade funcionalidades como paginación y filtros en las rutas GET.
Consejos para la Implementación en Producción
- Utiliza siempre HTTPS para la transmisión segura de datos.
- Asegúrate de que las credenciales de la base de datos estén correctamente almacenadas en un archivo
.envy no en el código fuente. - Considera usar un servidor como Nginx o Apache para servir la API de forma eficiente.