Skip to content

Capítulo 2.5: Rutas API

Tiempo de estudio: 45 minutos


1. ¿Qué es una ruta? Explicación sencilla

Imagina que tu controlador (PlanetController) es un gran centro de oficinas, y cada uno de sus métodos (index, store, show) es un departamento separado que realiza su trabajo.

Una Ruta (Route) es una placa de dirección en la entrada del edificio. Dice:

  • "Si alguien llegó a la dirección /planets con el método GET — envíelo al departamento index (mostrar todo)".
  • "Si alguien llegó a la dirección /planets con el método POST con un paquete (datos) — envíelo al departamento store (crear uno nuevo)".

Sin rutas, ninguna solicitud del mundo exterior encontrará el departamento que necesita en tu código. El archivo principal para estas "placas de dirección" en la API es routes/api.php.

En Laravel 11+, por defecto no hay una "libreta de direcciones API". La creamos nosotros mismos ejecutando el comando php artisan install:api. Ahora tenemos el archivo routes/api.php, que es el centro de control principal para todas las rutas de nuestra API.

Diferencia clave entre api.php y web.php:

  • Prefijo /api: Laravel añade automáticamente /api a todas las URLs de este archivo. La ruta /planets se convierte en /api/planets.
  • "Sin estado" (Stateless): Aquí no hay sesiones ni cookies, como en la web normal. Cada solicitud es independiente y debe contener toda la información para la autenticación (normalmente, un token de API en los encabezados).

2. El camino del novato: Creación manual de una ruta

Vamos a crear una única ruta manualmente para entender el principio. Nuestro objetivo es hacer que la URL /api/planets muestre una lista de todos los planetas.

Abre routes/api.php y escribe:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PlanetController; // Indicamos dónde está nuestro controlador

//                    (1)           (2)                     (3)
Route::get(      '/planets',    [PlanetController::class, 'index']     );
//   ^               ^                       ^
// (Método HTTP)   (URL)             (Qué controlador y método llamar)

Analicemos esta línea por partes:

  1. Route::get(...) — decimos: "Esta ruta solo funciona para solicitudes GET".
  2. '/planets' — es la URL que Laravel escuchará. Con el prefijo /api, la dirección completa será http://space-api.test/api/planets.
  3. [PlanetController::class, 'index'] — es el "punto de destino". Decimos: "Cuando llegue la solicitud, encuentra la clase PlanetController y llama a su método index()".

¡Ahora todo está conectado! Solicitud -> Ruta -> Controlador -> Método.

¿Y si necesitamos obtener un planeta por su ID? Por ejemplo, /api/planets/5.

// Ruta para obtener un planeta específico
Route::get('/planets/{planet}', [PlanetController::class, 'show']);

Aquí {planet} es una "plantilla" o variable. Laravel entiende que en este lugar puede haber cualquier cosa (ID, slug). Luego, pasa este valor al método show(Planet $planet). Esta "magia", cuando Laravel encuentra el planeta por ID automáticamente, se llama Route Model Binding.


3. El camino del maestro: apiResource — una línea para gobernarlos a todos

Crear cada ruta manualmente (para index, show, store, update, destroy) es tedioso. Los desarrolladores de Laravel lo entienden, por eso crearon un asistente potente — apiResource.

Elimina todo lo que escribimos y reemplázalo con una sola línea:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PlanetController;

Route::apiResource('planets', PlanetController::class);

¿Qué hace esta sola línea bajo el capó? Crea automáticamente un conjunto completo de rutas para las operaciones CRUD estándar que ya implementamos en el controlador.

Método URL Se dirige al método Propósito
GET /api/planets index() Obtener una lista de todos los planetas
POST /api/planets store() Crear un nuevo planeta
GET /api/planets/{planet} show() Mostrar un planeta específico
PUT/PATCH /api/planets/{planet} update() Actualizar un planeta existente
DELETE /api/planets/{planet} destroy() Eliminar un planeta

Puedes Verificarlo tú mismo. Ejecuta el siguiente comando en la terminal:

php artisan route:list --path=api

Verás una tabla con todas las rutas creadas. apiResource es tu mejor amigo para ahorrar tiempo al crear APIs estándar.


4. Misiones especiales y orden de las rutas

¿Qué pasa si necesitamos una ruta no estándar, que no está en apiResource? Por ejemplo, obtener un planeta aleatorio en la dirección /api/planets/random.

Vamos a añadirla. Pero aquí hay una trampa mortal en la que caen 9 de cada 10 novatos.

Orden incorrecto (¡NO FUNCIONA!):

Route::apiResource('planets', PlanetController::class);
Route::get('/planets/random', [PlanetController::class, 'random']); // <-- NO FUNCIONARÁ
¿Por qué? Laravel lee las rutas de arriba a abajo. Verá Route::apiResource, que creó la ruta GET /planets/{planet}. Cuando solicites /planets/random, Laravel pensará que "random" es el ID de un planeta e intentará encontrar en la base de datos un planeta con el ID "random", y obtendrás un error.

Orden correcto (¡FUNCIONA!):

<?php
use App\Http\Controllers\PlanetController;
use Illuminate\Support\Facades\Route;

// 1. Primero declaramos las rutas ESPECÍFICAS
Route::get('/planets/random', [PlanetController::class, 'random']);

// 2. Y solo después declaramos las rutas GENERALES con variables
Route::apiResource('planets', PlanetController::class);

⚠️ ¡Importante!

Para probar la ruta api/planets/random, debes añadir un nuevo manejador en PlanetController:

<?php
public function random(Request $request)
{
   $planet = Planet::inRandomOrder()->first();
   return response()->json($planet);
}

Regla: Declara siempre las rutas más específicas (como /random) antes de las rutas más generales y con plantillas (como /{planet}).


5. Agrupación: Poniendo orden

Cuando hay muchas rutas, se pueden y se deben agrupar.

A. Versionado de la API Para no romper las aplicaciones antiguas que usan tu API en el futuro, es costumbre añadir una versión en la URL, por ejemplo /api/v1/....

<?php
Route::prefix('v1')->group(function () {
    // Todas las rutas dentro de este grupo obtendrán el prefijo /v1
    // URL final: /api/v1/planets
    Route::get('/planets/random', [PlanetController::class, 'random']);
    Route::apiResource('planets', PlanetController::class);
});

B. Protección de rutas (Middleware) Imagina que cualquiera puede ver los planetas, pero solo los usuarios autorizados pueden crearlos, actualizarlos y eliminarlos.

<?php
// Rutas públicas, accesibles para todos
Route::get('/planets', [PlanetController::class, 'index']);
Route::get('/planets/{planet}', [PlanetController::class, 'show']);

// Grupo de rutas que requieren un "pase" (autenticación)
Route::middleware('auth:sanctum')->group(function () {
    Route::post('/planets', [PlanetController::class, 'store']);
    Route::put('/planets/{planet}', [PlanetController::class, 'update']);
    Route::delete('/planets/{planet}', [PlanetController::class, 'destroy']);
});

Aquí middleware('auth:sanctum') es como un guardia de seguridad que comprueba el "pase" de cualquiera que intente acceder a las rutas dentro del grupo.


6. Pruebas con Postman

Ahora que todas las rutas están establecidas, es hora de probarlas.

  1. Si usas Herd: Tu sitio ya está funcionando en una dirección como http://space-api.test.
  2. Si no: Inicia el servidor local con el comando php artisan serve. La dirección será http://localhost:8000.

Abre Postman y envía las solicitudes:

  • GET http://space-api.test/api/planets
  • GET http://space-api.test/api/planets/random
  • POST http://space-api.test/api/planets (no olvides añadir el cuerpo de la solicitud JSON en la pestaña Body -> raw -> JSON).

Ejemplo de solicitud POST:

{
    "name": "Kepler-186f",
    "description": "Primera planeta de tamaño terrestre en la zona habitable",
    "size_km": 15000,
    "solar_system": "Kepler-186",
    "is_habitable": true
}


8. Errores comunes de enrutamiento

  1. 404 Not Found
    • URL incorrecta (/api/planet en lugar de /api/planets)
    • Olvidaste php artisan serve
  2. 405 Method Not Allowed
    • Método HTTP incorrecto (por ejemplo, GET en lugar de POST)
  3. Missing Controller
    • Error tipográfico en el nombre del controlador (PlanetControler)
  4. Route Name Collision
    • Nombres de ruta duplicados

Cuestionario de refuerzo

1. Archivo para rutas API en Laravel:

2. Prefijo automático para rutas API:

3. Método para crear 5 rutas CRUD:

4. Route::prefix('v1') se usa para:

5. Ver todas las rutas:


🚀 Resumen del capítulo:

¡Has construido las "rutas hiperespaciales" para la API espacial! Ahora:

  • 🗺️ Todos los endpoints están disponibles en /api/...
  • 🔗 Las rutas de recursos están conectadas al controlador
  • 🛡️ Se han añadido rutas personalizadas para operaciones especiales
  • ✅ Las rutas se han probado con Postman

¡El universo está abierto a solicitudes! A continuación, añadiremos protección contra la "basura espacial": la validación de datos.

📌 Verificación:

  1. Ejecuta php artisan route:list
  2. Asegúrate de ver 5+ rutas para planets
  3. Verifica el funcionamiento de GET /api/planets en el navegador/Postman

⚠️ Si error 404:

  • Verifica la presencia de Route::apiResource en routes/api.php
  • Asegúrate de que el servidor esté en ejecución (php artisan serve)
  • Para Windows: permite el puerto 8000 en el firewall