Reputation:
I want to do paging at the Laravel API. As a result, I want to get data and status code type.
Controller :
public function index()
{
$data = PersonCollection::collection(Person::paginate(2));
return response()->json($data, 200);
}
PersonCollection Resource :
public function toArray($request)
{
return [
'id' => $this->id,
'first_name' => $this->first_name,
'last_name' => $this->last_name,
'email' => $this->email,
'phone' => $this->phone,
'city' => $this->city,
'href' => [
'link' => route('person.show', $this->id),
],
];
}
Output :
https://i.hizliresim.com/LvlBzj.png
[
{
"id": 1,
"first_name": "Burak Ali",
"last_name": "Ildır",
"email": "[email protected]",
"phone": "376.395.7233",
"city": "Koelpinstad",
"href": {
"link": "http://127.0.0.1:8000/api/v2/person/1"
}
},
{
"id": 2,
"first_name": "Vena",
"last_name": "Spinka",
"email": "[email protected]",
"phone": "716-268-7788 x092",
"city": "South Gudrunbury",
"href": {
"link": "http://127.0.0.1:8000/api/v2/person/2"
}
}
]
But I want.
https://i.hizliresim.com/LvlBWo.png
{
"data": [
{
"id": 1,
"first_name": "Burak Ali",
"last_name": "Ildır",
"email": "[email protected]",
"phone": "376.395.7233",
"city": "Koelpinstad",
"href": {
"link": "http://127.0.0.1:8000/api/v2/person/1"
}
},
{
"id": 2,
"first_name": "Vena",
"last_name": "Spinka",
"email": "[email protected]",
"phone": "716-268-7788 x092",
"city": "South Gudrunbury",
"href": {
"link": "http://127.0.0.1:8000/api/v2/person/2"
}
}
],
"links": {
"first": "http://127.0.0.1:8000/api/v1/person?page=1",
"last": "http://127.0.0.1:8000/api/v1/person?page=26",
"prev": null,
"next": "http://127.0.0.1:8000/api/v1/person?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 26,
"path": "http://127.0.0.1:8000/api/v1/person",
"per_page": 2,
"to": 2,
"total": 52
}
}
I want other page links. But when I convert it to JSON data, links and metadata do not come.
Upvotes: 2
Views: 5501
Reputation: 40673
A resource collection describes how a collection of models will be transmitted as JSON.
You seem to be using it for an individual model. What you need is:
public function toArray($request)
{
return $this->collection->map(function ($person) {
return [
'id' => $person->id,
'first_name' => $person->first_name,
'last_name' => $person->last_name,
'email' => $person->email,
'phone' => $person->phone,
'city' => $person->city,
'href' => [
'link' => route('person.show', $person->id),
],
];
});
}
However the recommended way is to make a PersonResource
instead in the same namespace and implement the toArray($request)
in that class:
Person
class Person extends Resource //The name is important
{
public function toArray($request)
{
return [
'id' => $this->id,
'first_name' => $this->first_name,
'last_name' => $this->last_name,
'email' => $this->email,
'phone' => $this->phone,
'city' => $this->city,
'href' => [
'link' => route('person.show', $this->id),
],
];
}
}
PersonCollection
class PersonCollection extends ResourceCollection
{
// This class is intentionally empty
}
Finally you should let Laravel handle how to make the response:
public function index()
{
$data = PersonCollection::collection(Person::paginate(2));
return $data->toResponse();
}
The default behaviour of the resource collection is to look for a resource which is named like the collection but with the Collection
part removed (in this case PersonCollection
will look for a Person
resource).
This should ensure each model is converted according to the resource and the pagination behaviour is maintained.
Upvotes: 2