How to create an API with laravel resources
When building an API, you may need a transformation layer that sits between your Eloquent models and the JSON responses that are actually returned to your application's users. Laravel's resource classes allow you to expressively and easily transform your models and model collections into JSON.
To generate a resource class, you may use the make:resource
Artisan command.
php artisan make:resource BookResource
A resource class represents a single model that needs to be transformed into a JSON structure. For example, here is a simple Book resource class:
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class BookResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
//transforms the resource into an array made up of the attributes to be converted to JSON
return [
'id'=> $this->id,
'title'=> $this->title,
'author' => $this->author,
'description'=>$this->description,
'created_at' => (string) $this->created_at,
'updated_at' => (string) $this->updated_at,
'user' => $this->user,
'ratings' => $this->ratings,
'average_rating' => $this->ratings->avg('rating')
];
}
}
Example how to use this resource:
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show(book $book)
{
return new BookResource($book);
}
Example with a collection of resources:
If you are returning a collection of resources or a paginated response, you may use the collection
method when creating the resource instance in your route or controller:
/**
* Display all books that have been added
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$books=Book::all();
return BookResource::collection($books);
}
Note that this does not allow any addition of meta data that may need to be returned with the collection. If you would like to customize the resource collection response, you may create a dedicated resource to represent the collection.
To create a resource collection, you should use the --collection
flag when creating the resource. Or, including the word Collection
in the resource name will indicate to Laravel that it should create a collection resource. Collection resources extend the Illuminate\Http\Resources\Json\ResourceCollection
class:
php artisan make:resource BookResource --collection
php artisan make:resource BookCollection
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class BookCollection extends ResourceCollection
{
/**
* Transform the resource collection into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'data' => $this->collection,
'links' => [
'self' => 'link-value',
],
];
}
}
After defining your resource collection, it may be returned from a route or controller:
use App\Http\Resources\BookCollection;
use App\Models\Book;
Route::get('/books', function () {
return new BookCollection(Book::all());
});
Example How to use Relationships in Resource
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'posts' => PostResource::collection($this->posts),
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}