In docs are written
Of course, you may be wondering if this will cause your outer-most resource to wrapped in two data keys. Don't worry, Laravel will never let your resources be accidentally double-wrapped, so you don't have to be concerned about the nesting level of the resource collection you are transforming:
It is true before we don't use pagination.
AppServiceProvider:
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Resource::withoutWrapping();
}
}
Resource:
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\Resource;
class Company extends Resource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'reg_number' => $this->reg_number,
'address' => $this->address,
'ceo' => $this->ceo,
'created_at' => $this->created_at->format('Y-m-d\TH:i:s\Z'),
'updated_at' => $this->updated_at->format('Y-m-d\TH:i:s\Z'),
];
}
}
ResourceCollection:
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class CompanyCollection extends ResourceCollection
{
/**
* Transform the resource collection into an array.
*
* @param \Illuminate\Http\Request
* @return array
*/
public function toArray($request)
{
return ['data' => $this->collection];
}
}
Controller:
class CompanyController extends Controller
{
public function getCompaniesList()
{
$companies = Company::all();
return new CompanyCollection($companies);
}
public function getCompaniesListPaginated()
{
$companies = Company::paginate(1);
return new CompanyCollection($companies);
}
public function getCompany($id)
{
$company = Company::find($id);
return new CompanyResource($company);
}
}
getCompany:{
"id": 1,
"name": "Reinger-Lynch",
"reg_number": "10526520",
"address": "2828 Ambrose Coves\nHudsonberg, IA 05000",
"ceo": "Sibyl Kuhn",
"created_at": "2013-04-29T10:33:40Z",
"updated_at": "2013-04-29T10:33:40Z"
}
getCompaniesList:{
"data": [
{
"id": 1,
"name": "Reinger-Lynch",
"reg_number": "10526520",
"address": "2828 Ambrose Coves\nHudsonberg, IA 05000",
"ceo": "Sibyl Kuhn",
"created_at": "2013-04-29T10:33:40Z", "2013-04-29T10:33:40Z"
},
...
]
}
getCompaniesListPaginated:{
"data": {
"data": [
{
"id": 1,
"name": "Reinger-Lynch",
"reg_number": "10526520",
"address": "2828 Ambrose Coves\nHudsonberg, IA 05000",
"ceo": "Sibyl Kuhn",
"created_at": "2013-04-29T10:33:40Z",
"updated_at": "2013-04-29T10:33:40Z"
},
...
]
},
"links": {
"first": "http:\/\/sahkoukko.dev\/api\/companies?page=1",
"last": "http:\/\/sahkoukko.dev\/api\/companies?page=10",
"prev": null,
"next": "http:\/\/sahkoukko.dev\/api\/companies?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 10,
"path": "http:\/\/sahkoukko.dev\/api\/companies",
"per_page": 1,
"to": 1,
"total": 10
}
}
When I comment out Resource::withoutWrapping(); all works fine. But this logic is incorrect. It must avoid double wrapping to data with pagination.
The problem is that, when you use pagination, the resource MUST be wrapped because there is meta data. You are also forcing wrapping by using:
public function toArray($request)
{
return ['data' => $this->collection];
}
So with pagination, your collection is automatically wrapped and since you're hardcoding a wrap, then it gets double-wrapped.
From the docs
When returning paginated collections in a resource response, Laravel will wrap your resource data in a data key even if the withoutWrapping method has been called. This is because paginated responses always contain meta and links keys with information about the paginator's state
You should just return $this->collection and control wrapping with the 'wrap' method.
Then there are no any easy solution to return:
Sure it is. Watch Taylor's Laracon EU presentation where he covers resources in detail. He talks about each of these.
@vgladimir i have been reading the Laravel Resource code and you should create a public static property named $wrap (public static $wrap = 'results'; for example).
I hope it helps you.
I just create an issue: https://github.com/laravel/internals/issues/862