I have been working with laravel api resource. By default laravel provides links and meta as shown below.
"links": {
"first": "https://demo.test/api/v2/taxes?page=1",
"last": "https://demo.test/api/v2/taxes?page=4",
"prev": null,
"next": "https://demo.test/api/v2/taxes?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 4,
"path": "https://demo.test/api/v2/taxes",
"per_page": 2,
"to": 2,
"total": 8
}
But I don't want this, insted i want something like
"pagination": {
"total": 8,
"count": 8,
"per_page": 25,
"current_page": 1,
"total_pages": 1
}
I'm able to get this info but if I do return TaxResource::collection($taxes);
, I won't get this. Even I have custom collection method
public static function collection($resource)
{
$resource->pagination = [
'total' => $resource->total(),
'count' => $resource->count(),
'per_page' => $resource->perPage(),
'current_page' => $resource->currentPage(),
'total_pages' => $resource->lastPage()
];
return parent::collection($resource);
}
It is not giving what I want. But if I reference through (TaxResource::collection($taxes))->pagination;
I'm able to get that. But I want it to be returned when I do return TaxResource::collection($taxes);
I was interested in your question and spent some time resolving it. I guess there are a lot of work to be done to improve Eloquent: API Resources' functionality in the future.
In order to resolve it I must use Resource Collections instead of Resources:
However, if you need to customize the meta data returned with the collection, it will be necessary to define a resource collection
php artisan make:resource Tax --collection
or
php artisan make:resource TaxCollection
Route:
Route::get('/get-taxes', function () {
$taxes = Taxes::paginate();
return new TaxCollection($taxes);
});
TaxCollection.php:
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class TaxCollection extends ResourceCollection
{
public function toArray($request)
{
return [
'data' => $this->collection,
'pagination' => [
'total' => $this->total(),
'count' => $this->count(),
'per_page' => $this->perPage(),
'current_page' => $this->currentPage(),
'total_pages' => $this->lastPage()
],
];
}
// Using Laravel < 5.6
public function withResponse($request, $response)
{
$originalContent = $response->getOriginalContent();
unset($originalContent['links'],$originalContent['meta']);
$response->setData($originalContent);
}
// Using Laravel >= 5.6
public function withResponse($request, $response)
{
$jsonResponse = json_decode($response->getContent(), true);
unset($jsonResponse['links'],$jsonResponse['meta']);
$response->setContent(json_encode($jsonResponse));
}
}
This solve the problem but now there are new one:
Unlike Resources I don't know how to modify toArray
fields in Resource Collections, the manual shows only example with 'data' => $this->collection
where we send not modified collection (Resource Collections allows us change meta data). So If we use just Resource then we can modify collection data but not meta data.
The accepted answer did not work for me (in Laravel 5.6), but I found a better way IMHO.
Save the pagination informations in your ResourceCollection constructor and replace the Paginator resource with the underlying Collection.
TaxCollection.php:
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class TaxCollection extends ResourceCollection
{
private $pagination;
public function __construct($resource)
{
$this->pagination = [
'total' => $resource->total(),
'count' => $resource->count(),
'per_page' => $resource->perPage(),
'current_page' => $resource->currentPage(),
'total_pages' => $resource->lastPage()
];
$resource = $resource->getCollection();
parent::__construct($resource);
}
public function toArray($request)
{
return [
'data' => $this->collection,
'pagination' => $this->pagination
];
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With