Skip to content

Capítulo 2.4: Controlador API PlanetController

Tiempo de estudio: 1 hora


1. Controlador: Centro de control de objetos espaciales

En la arquitectura MVC, el controlador es un intermediario entre los modelos y las solicitudes:

  • 📡 Recibe solicitudes HTTP (GET, POST, PUT, DELETE)
  • 🔍 Extrae datos de la base de datos a través de los modelos
  • 📦 Genera respuestas JSON para la API

💡 Analogía espacial: PlanetController = Centro de Control de Misión:

  • Recibe solicitudes de la Tierra (GET /planets)
  • Envía comandos a las "sondas" (modelos)
  • Devuelve la telemetría en formato JSON

2. Creación de un controlador de recursos

Un controlador de recursos incluye automáticamente métodos para operaciones CRUD.

Paso 1: Generación del controlador

php artisan make:controller PlanetController --api --model=Planet

Lo que se creará en app/Http/Controllers/PlanetController.php:

<?php

namespace App\Http\Controllers;

use App\Models\Planet;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule; // No olvides añadir esta importación

class PlanetController extends Controller
{
    // Mostrar lista de planetas
    public function index(Request $request) {}

    // Crear una nueva planeta
    public function store(Request $request) {}

    // Mostrar una planeta específica
    public function show(Planet $planet) {}

    // Actualizar planeta
    public function update(Request $request, Planet $planet) {}

    // Eliminar planeta
    public function destroy(Planet $planet) {}
}


3. Implementación de los métodos de la API

A. index() - Obtener lista de planetas

<?php
public function index(Request $request)
{
    // Obtenemos las planetas con paginación, 15 por página
    $planets = Planet::paginate($request->get('per_page', 15));
    return response()->json($planets); // Automáticamente 200 OK
}

B. store() - Crear una nueva planeta

<?php
public function store(Request $request)
{
    $data = $request->validate([
        'name' => 'required|string|max:255|unique:planets',
        'description' => 'required|string',
        'size_km' => 'required|integer|min:100',
        'solar_system' => 'required|string|max:100',
        'image_url' => 'nullable|url',
        'is_habitable' => 'boolean'
    ]);

    $planet = Planet::create($data);
    return response()->json($planet, 201); // 201 Creado
}

C. show() - Ver una planeta

<?php
public function show(Planet $planet)
{
    return response()->json($planet); // Automáticamente 200 OK
}

D. update() - Actualizar planeta

<?php
public function update(Request $request, Planet $planet)
{
    $data = $request->validate([
        'name' => [
            'string',
            'max:255',
            Rule::unique('planets')->ignore($planet->id),
        ],
        'description' => 'sometimes|string', // 'sometimes' - validar solo si el campo está presente
        'size_km' => 'sometimes|integer|min:100',
        'solar_system' => 'sometimes|string|max:100',
        'image_url' => 'sometimes|nullable|url',
        'is_habitable' => 'sometimes|boolean'
    ]);

    $planet->update($data);
    return response()->json($planet); // 200 OK
}

E. destroy() - Eliminar planeta

<?php
public function destroy(Planet $planet)
{
    $planet->delete();
    return response()->json(null, 204); // 204 Sin Contenido
}


4. Enlace de Modelo de Ruta (Route Model Binding)

Laravel sustituye automáticamente el objeto del planeta por ID:

// En la ruta: GET /planets/{planet}
// En el método: show(Planet $planet)

  • Si no se encuentra el planeta → automáticamente 404
  • No hay necesidad de consultas manuales findOrFail()

5. Formato de las respuestas

Ejemplo de respuesta mejorada para index():

<?php
public function index()
{
    return response()->json([
        'success' => true,
        'data' => Planet::all(),
        'message' => 'Planetas obtenidos exitosamente'
    ]);
}

Respuesta en caso de error 404 (automáticamente):

{
    "message": "No query results for model [App\\Models\\Planet] 123",
    "exception": "Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException"
}


Cuestionario de repaso

1. Bandera para crear un controlador API:

2. ¿Qué estado devolver al crear exitosamente?

3. El Enlace de Modelo de Ruta (Route Model Binding) permite:

4. Al eliminar un planeta, devolvemos:

5. $request->validate() se usa para:


🚀 Resumen del capítulo:

¡Has creado el "panel de control" del sistema planetario! Ahora tu controlador puede:

  • 🌌 Mostrar una lista de planetas (index)
  • 🪐 Crear nuevos mundos (store)
  • 🔭 Detallar los datos de un planeta (show)
  • 🛠️ Actualizar la información (update)
  • 💥 Destruir planetas (destroy)

¡Solo falta trazar las rutas! En el siguiente capítulo conectaremos el controlador a las rutas de la API.

📌 Verificación:

Asegúrate de que en app/Http/Controllers exista PlanetController.php con 5 métodos.

⚠️ Si hay errores:

  • Verifica el nombre del modelo: use App\Models\Planet;
  • Verifica las importaciones
  • Para PostgreSQL: asegúrate de que Planet::all() devuelva datos
  • Si hay problemas con Tinker: ejecuta composer dump-autoload