Laravel API Resource and Resource Collections

Summary: Build structured APIs using Resources.


Modern web applications often rely on clean, efficient RESTful APIs to deliver data. Laravel, one of the most popular PHP frameworks, provides a powerful tool for API development: API Resources. With Laravel API Resources and Resource Collections, developers can convert models and collections into JSON responses effortlessly, guaranteeing a well-structured and standardized output.

In this article, we will explore:

  • What Laravel API Resources and Resource Collections are
  • How to create and use them
  • Advanced resource features
  • Best practices

What are Laravel API Resources?

Laravel API Resources are a way to transform your database models and collections into JSON that your frontend or external consumers can easily use. They allow you to finely control exactly how your data is shaped and presented, decoupling your raw database structure from your API responses.

Benefits:

  • Consistent structure: Enforce output formats across endpoints.
  • Easy modifications: Quickly adjust fields shown without changing your underlying models or controllers.
  • Encapsulation: Hide sensitive attributes and show computed properties as needed.

Creating API Resources

Laravel ships with handy Artisan commands for generating resources.

To create a resource:

php artisan make:resource BookResource

This creates:

// app/Http/Resources/BookResource.php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class BookResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     */
    public function toArray(Request $request): array
    {
        // Return an array of fields to represent this resource
        return [
            'id' => $this->id,
            'title' => $this->title,
            'author' => $this->author->name,
            'published_at' => $this->published_at->toDateString(),
        ];
    }
}

Use the resource in your controllers:

use App\Http\Resources\BookResource;
use App\Models\Book;

public function show($id)
{
    $book = Book::findOrFail($id);
    return new BookResource($book);
}

Resulting JSON:

{
  "id": 1,
  "title": "Clean Code",
  "author": "Robert C. Martin",
  "published_at": "2008-08-01"
}

Resource Collections

Often, you'll want to return a list of resources (for example, all books). You can wrap collections with resource classes for consistent transformation.

You can explicitly create a collection resource:

php artisan make:resource BookCollection

However, you can simply use the same BookResource:

public function index()
{
    return BookResource::collection(Book::all());
}

Sample JSON Output:

{
  "data": [
    {
      "id": 1,
      "title": "Clean Code",
      "author": "Robert C. Martin",
      "published_at": "2008-08-01"
    },
    {
      "id": 2,
      "title": "Refactoring",
      "author": "Martin Fowler",
      "published_at": "1999-06-28"
    }
  ]
}

Note: The output includes a data wrapper by default, which aids consistency with JSON:API and provides flexibility for meta-information.


Adding Meta Data

Enhance API responses by adding meta fields, like pagination info:

public function index()
{
    return BookResource::collection(Book::paginate(10))
           ->additional([
                'meta' => [
                    'publisher' => 'Sample Publishers, Inc.'
                ]
           ]);
}

Result:

{
  "data": [ /* books */ ],
  "links": { /* pagination links */ },
  "meta": {
    "publisher": "Sample Publishers, Inc.",
    "current_page": 1,
    // ...more pagination meta
  }
}

Conditional Fields and Relationships

You can conditionally embed fields and relationships:

public function toArray($request)
{
    return [
        'id' => $this->id,
        'title' => $this->title,
        'author' => $this->author->name,
        'reviews' => ReviewResource::collection(
            $this->whenLoaded('reviews')
        ),
        'summary' => $this->when($this->summary, $this->summary),
    ];
}
  • Use whenLoaded to include relationships only if they've been eager loaded.
  • Use when to conditionally add fields.

Best Practices

  • Avoid returning raw models from API endpoints.
  • Use resources everywhere: Even for simple cases, APIs benefit from the consistency.
  • Group related resources into separate classes (e.g., AuthorResource, ReviewResource).
  • Hide sensitive fields (e.g., internal IDs, security info).
  • Leverage eager loading and whenLoaded for efficient relationship handling.

Conclusion

Laravel API Resources and Resource Collections provide developers with a robust toolkit for designing clean, standardized RESTful APIs. By transforming models and collections in a centralized way, you can iterate rapidly, avoid leaking internal data structures, and present exactly the data your clients need.

Start using resources in your Laravel APIs to deliver reliable, clear, and maintainable responses your consumers will love.


Further Reading: