Contenido del curso

Recursos y colecciones en Laravel API

Resumen

Diseñar una API estable empieza por separar la consulta de base de datos de la forma en que se entrega la respuesta. En Laravel, los resources y las collections permiten aislar esa estructura para que cada endpoint devuelva los mismos campos sin importar cómo se construya la consulta. Si trabajas con APIs REST y quieres consistencia editorial en tus respuestas JSON, esta es la pieza que te falta.

¿Qué es un recurso y por qué importa aislarlo?

Un recurso representa el dato que quieres devolver desde tu base de datos, pero con una estructura definida por ti, no por la consulta.

El problema aparece cuando modificas la respuesta endpoint por endpoint. Si en una receta usas select('id','title') y en otra traes el modelo completo, terminas con respuestas inconsistentes: en una aparece el usuario y la categoría, en otra solo el título. El recurso debe ser el mismo sin importar la consulta [01:30].

¿Qué es un API Resource en Laravel? Es una clase que define cómo se transforma un modelo en JSON. Decides qué campos mostrar, cómo nombrarlos y qué relaciones incluir, sin tocar la consulta original.

¿Cómo se crea un recurso con Artisan?

Usas el comando php artisan make:resource CategoryResource. La convención es nombrar la clase con el sufijo Resource para distinguirla.

Esto genera una nueva carpeta y un archivo donde defines el método toArray. Allí estructuras la respuesta de forma personalizada [03:10]:

  • id: el identificador del modelo.
  • type: una etiqueta manual como categoría que describe el recurso.
  • attributes: un arreglo con los campos visibles, por ejemplo name.
  • relationships: las relaciones asociadas, como las recetas vinculadas.

php public function toArray($request) { return [ 'id' => $this->id, 'type' => 'categoría', 'attributes' => [ 'name' => $this->name, ], 'relationships' => [ 'recetas' => $this->recetas, ], ]; }

¿Cómo uso el recurso desde el controlador?

En el controlador importas la clase con use y la instancias pasando el modelo como parámetro. Para mayor orden, guarda la consulta en una variable y luego retorna el recurso [05:20].

php $category = Category::findOrFail($id); return new CategoryResource($category);

Al visitar el endpoint, la respuesta llega ordenada bajo la llave data, con su id, type, attributes y relationships. Esto es coherencia: cualquier consulta que retorne una categoría va a devolver exactamente esta forma.

¿Y cuándo usar una colección en lugar de un recurso?

Una colección sirve cuando devuelves múltiples elementos. Laravel ofrece el acceso estático ::collection() directamente sobre el recurso [06:40].

php return CategoryResource::collection(Category::all());

Con esto, cada elemento del listado hereda la misma estructura del recurso. El estándar se mantiene: data, id, type, attributes y relationships para cada categoría.

¿Cómo personalizo una colección para que omita relaciones?

A veces el listado no necesita cargar todas las relaciones del recurso individual. La solución es crear una resource collection dedicada con php artisan make:resource CategoryCollection [08:15].

Este archivo es hermano del recurso, pero hereda de ResourceCollection en lugar de JsonResource. Aquí defines un comportamiento distinto usando el método map para iterar la colección y aplicar una transformación a cada elemento.

php public function toArray($request) { return $this->collection->map(function ($category) { return [ 'id' => $category->id, 'type' => 'categoría', 'attributes' => [ 'name' => $category->name, ], ]; })->toArray(); }

¿Por qué se usa toArray() al final del map? Porque Laravel espera un arreglo en la respuesta del recurso. El método map devuelve una colección, así que toArray() la convierte al formato correcto y evita el error de tipos.

¿Cuál es la diferencia práctica entre ambos archivos?

El recurso individual mantiene relaciones completas como las recetas asociadas. La colección, en cambio, entrega un listado más liviano sin esas relaciones, ideal para vistas de índice [10:30].

En el controlador, el método index usa la colección y el método show usa el recurso individual:

php public function index() { return new CategoryCollection(Category::all()); }

public function show($id) { return new CategoryResource(Category::findOrFail($id)); }

Así decides exactamente qué campos mostrar y cuáles ocultar según el contexto, sin tocar nunca la consulta a base de datos. La estructura vive en el recurso, no en el controlador.

Si trabajas con otro framework como Express, Django o Rails, cuéntame en los comentarios cómo logras este mismo aislamiento de la respuesta.