Laravel's API Resources provide a powerful and elegant way to transform your Eloquent models and model collections into JSON responses. Whether you're building a REST API or need structured data output, resources give you complete control over how your data is presented to consumers.
In this comprehensive guide, we'll explore both individual Resources and Resource Collections, including automatic pagination handling in Laravel 12.
What are Laravel Resources ?
Laravel Resources act as a transformation layer between your Eloquent models and the JSON responses that are returned to users of your application. They allow you to expressively and easily transform models and model collections into JSON.
Basic Resource Implementation
Let's start with a simple ArticleResource
that transforms an Article model:
The Model
First, here's our basic Article model:
<?php
declare(strict_types=1);
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
use HasFactory;
protected $fillable = ['title', 'body', 'published_at'];
protected $casts = ['published_at' => 'datetime'];
}
The Resource
<?php
declare(strict_types=1);
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
final class ArticleResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'title' => $this->title,
'body' => $this->body,
'published_at' => optional($this->published_at)?->toIso8601String(),
'created_at' => $this->created_at->toIso8601String(),
];
}
}
Using the Resource
In your controller, you can use the resource like this:
<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use App\Http\Resources\ArticleResource;
use App\Models\Article;
final class ArticleController extends Controller
{
public function show(Article $article): ArticleResource
{
return new ArticleResource($article);
}
}
This will return a JSON response like:
{
"data": {
"id": 1,
"title": "Understanding Laravel Resources",
"body": "Laravel Resources provide a powerful way...",
"published_at": "2024-01-15T10:30:00Z",
"created_at": "2024-01-15T08:00:00Z"
}
}
Resource Collections with Automatic Pagination
When dealing with multiple models, Laravel provides Resource Collections. Here's where Laravel 12's auto-mapping feature really shines:
The Collection Resource
<?php
declare(strict_types=1);
namespace App\Http\Resources;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use JsonSerializable;
final class ArticleCollection extends JsonResource
{
/** Map each item with ArticleResource automatically */
public string $collects = ArticleResource::class;
/** Preserve default structure (data + links + meta if paginator) */
public function toArray(Request $request): array|JsonSerializable|Arrayable
{
return parent::toArray($request);
}
public function with($request): array
{
return [
'meta_extra' => ['generate_at' => now()->toIso8601String()]
];
}
}
Using the Collection with Pagination
<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use App\Http\Resources\ArticleCollection;
use App\Models\Article;
final class ArticleController extends Controller
{
public function index(): ArticleCollection
{
return new ArticleCollection(
Article::query()->latest()->paginate(10)
);
}
}
Setting up Routes
<?php
use App\Http\Controllers\ArticleController;
use Illuminate\Support\Facades\Route;
Route::get('/articles', [ArticleController::class, 'index'])->name('articles.index');
Route::get('/articles/{article}', [ArticleController::class, 'show'])->name('articles.show');
The Magic: Laravel 12's Auto-Collection Feature
The key innovation in the ArticleCollection
is the $collects
property:
public string $collects = ArticleResource::class;
This tells Laravel to automatically wrap each item in the collection with the specified resource class. When you pass a paginated collection to this resource, Laravel will:
-
Automatically map each article through
ArticleResource
- Preserve pagination metadata (current page, total, links, etc.)
-
Maintain the default Laravel structure with
data
,links
, andmeta
keys
Response Structure
Single Resource Response
{
"data": {
"id": 1,
"title": "Understanding Laravel Resources",
"body": "Laravel Resources provide a powerful way...",
"published_at": "2024-01-15T10:30:00Z",
"created_at": "2024-01-15T08:00:00Z"
}
}
Paginated Collection Response
{
"data": [
{
"id": 1,
"title": "Understanding Laravel Resources",
"body": "Laravel Resources provide a powerful way...",
"published_at": "2024-01-15T10:30:00Z",
"created_at": "2024-01-15T08:00:00Z"
},
{
"id": 2,
"title": "Another Article",
"body": "Content of another article...",
"published_at": "2024-01-16T14:20:00Z",
"created_at": "2024-01-16T12:00:00Z"
}
],
"links": {
"first": "http://example.com/articles?page=1",
"last": "http://example.com/articles?page=5",
"prev": null,
"next": "http://example.com/articles?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 5,
"path": "http://example.com/articles",
"per_page": 10,
"to": 10,
"total": 50
},
"meta_extra": {
"generate_at": "2024-01-15T15:45:30Z"
}
}
Key Benefits
1. Automatic Item Transformation
The $collects
property eliminates the need to manually loop through items and apply transformations.
2. Preserved Pagination
Laravel automatically maintains all pagination metadata, including links and meta information.
3. Consistent Structure
Your API responses maintain a consistent structure whether returning single items or collections.
4. Extensible
You can easily add extra metadata using the with()
method without disrupting the core structure.
5. Type Safety
With proper typing, you get better IDE support and early error detection.
Best Practices
- Use final classes for resources when you don't plan to extend them
- Declare strict types for better type safety
-
Handle optional relationships gracefully with
optional()
- Use ISO 8601 format for dates in APIs
- Keep transformations simple - complex logic should be in the model or service layer
Conclusion
Laravel Resources and Collections provide an elegant solution for API response transformation. The auto-collection feature in Laravel 12 makes working with paginated data seamless while maintaining flexibility for customization.
By leveraging the $collects
property and proper resource structure, you can build robust, consistent APIs with minimal code while taking advantage of Laravel's powerful pagination features.
Whether you're building a simple REST API or a complex data transformation layer, Laravel Resources offer the perfect balance of simplicity and power for your application's needs.
Top comments (0)