How to get laravel eloquent data toArray with pagination - laravel

Here is my code.
$orders = Order::with('customer')->withCount('orderItems')->paginate(50)->toArray();
This code return me the blank page. No data return. So here's what I did wrong?

When you are using Laravel pagination, it simply gives you an array of Data.
You don't need to convert to toArray().Use the following code :
$orders = Order::with('customer')->withCount('orderItems')->paginate(15);
The response of the pagination will be the following :
Content-Type: application/vnd.api+json
{
"meta": {
"page": {
"current-page": 2,
"per-page": 15,
"from": 16,
"to": 30,
"total": 50,
"last-page": 4
}
},
"links": {
"first": "http://localhost/api/v1/posts?page[number]=1&page[size]=15",
"prev": "http://localhost/api/v1/posts?page[number]=1&page[size]=15",
"next": "http://localhost/api/v1/posts?page[number]=3&page[size]=15",
"last": "http://localhost/api/v1/posts?page[number]=4&page[size]=15"
},
"data": [...]
}

Related

Laravel JSON Pagination: How to remove the arrows from next/previous link?

I'm using Laravel 8.20.1 and my API route returns a paginated JSON response.
Is there a better way than str_replace() to remove the arrows from the labels?
routes/api.php:
Route::middleware('auth:sanctum')->get('/items', function (Request $request) {
return new ItemCollection(Item::paginate(5));
});
response.data.meta
{
"current_page": 1,
"from": 1,
"last_page": 3,
"links": [
{
"url": null,
"label": "« Previous",
"active": false
},
....
{
"url": "http://localhost/api/items?page=2",
"label": "Next »",
"active": false
}
],
"path": "http://localhost/api/items",
"per_page": 5,
"to": 5,
"total": 15
}
Those labels for Next and Previous are in the translation files, resources/lang/en/pagination.php. If you look at Illuminate\Pagination\LengthAwarePaginator::linkCollection you can see it building the links part of the response.

Laravel - Change pagination root url

I am building an API Gateway and I am having a small problem returning the pagination urls from a microservice to the API Gateway.
This is the current structure of my API Gateway:
When I call the microservice, I can easily pass the paging parameters using the request data:
HTTP::get('http://api.billing.microservice.test/v2/invoices', $request->all());
However, when I make a request for a microservice, it returns the requested data, but with the URL of the microservice:
{
"data": [
# data returned from billing microservice with the billing API URL
],
"links": {
"first": "http://api.billing.microservice.test/v2/invoices?page=1",
"last": "http://api.billing.microservice.test/v2/invoices?page=10",
"prev": null,
"next": "http://api.billing.microservice.test/v2/invoices?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 10,
"path": "http://api.billing.microservice.test/v2/invoices",
"per_page": 30,
"to": 30,
"total": 300
}
}
However I need the return to have the main API URL:
{
"data": [
# data returned from billing microservice with the main API Address
],
"links": {
"first": "http://api.main.test/v2/invoices?page=1",
"last": "http://api.main.microservice.test/v2/invoices?page=10",
"prev": null,
"next": "http://api.main.test/v2/invoices?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 10,
"path": "http://api.main.test/v2/invoices",
"per_page": 30,
"to": 30,
"total": 300
}
}
Has anyone had to do something similar? What is the best way to achieve the desired results? Do a replace using some kind of regex? Is there anything I can do inside the microservice?
I was able to solve my problem with a simple method that already exists:
Model::paginate()->setPath('http://api.main.microservice.test/v2/invoices');
The result is:
{
"data": [
# data
],
"links": {
"first": "http://api.main.microservice.test/v2/invoices?page=1",
"last": "http://api.main.microservice.test/v2/invoices?page=1",
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"path": "http://api.main.microservice.test/v2/invoices",
"per_page": 30,
"to": 3,
"total": 3
}
}

Laravel: Results of paginate() are inconstant across pages

I am having issue with the paginated results as follows :
Request :
GET http://localhost:1000/api/v1/public/blog/articles
Response :
{
"current_page": 1,
"data": [
{
"article_id": 43
},
{
"article_id": 107
},
{
"article_id": 171
},
{
"article_id": 22
},
{
"article_id": 86
},
{
"article_id": 150
},
{
"article_id": 1
},
{
"article_id": 65
},
{
"article_id": 129
},
{
"article_id": 44
}
],
"first_page_url": "http://localhost:1000/api/v1/public/blog/articles?page=1",
"from": 1,
"last_page": 18,
"last_page_url": "http://localhost:1000/api/v1/public/blog/articles?page=18",
"next_page_url": "http://localhost:1000/api/v1/public/blog/articles?page=2",
"path": "http://localhost:1000/api/v1/public/blog/articles",
"per_page": "10",
"prev_page_url": null,
"to": 10,
"total": 179
}
So, now If I request again in the same link, it shows a different set of articles with different ids.
Also If I go to page=1 or page=2, each and every pages the results are inconstant.
I am not sure from where this issue is occuring,
I want to mention that my other paginated queries are working fine except when I am trying to concat queries for getting a specific result as follows :
$query = DB::query();
// Then Concatenating other queries based on options
// Now Execute The Whole Query
$fetched_articles = $query->paginate(5);
It would be helpful, if anyone can describe the paginator flows here with the solution or workarounds.
Thanks in Advance !
According to Laravel documentation
Currently, pagination operations that use a groupBy statement cannot
be executed efficiently by Laravel. If you need to use a groupBy with
a paginated result set, it is recommended that you query the database
and create a paginator manually.
so, you can not use groupBy in your query, if you want pagination.
By the way, you can try this blog post, may be it will work for you.

Why JSON structure of default pagination response and eloquent pagination resource are different?

I'm developing an API, and for index routes, I return paginated but now I should using eloquent resources, but pagination JSON structure of these two are different and front-end code doesn't work anymore.
my codes are:
// AdminUserController.php
public function index()
{
return User::paginate();
}
// ClientUserController.php
public function index()
{
return new UserCollection(User::paginate());
}
the first JSON structure like :
{
"total": 50,
"per_page": 15,
"current_page": 1,
"last_page": 4,
"next_page_url": "http://my.app/api/admin/users?page=2",
"prev_page_url": null,
"from": 1,
"to": 15,
"data": [
{
// Result Object
},
{
// Result Object
}
]
}
But the second is like:
{
"data": [
{
// Result Object
},
{
// Result Object
}
],
"links":{
"first": "http://my.app/api/app/users?page=1",
"last": "http://my.app/api/app/users?page=2",
"prev": null,
"next": null
},
"meta":{
"current_page": 1,
"from": 1,
"last_page": 2,
"path": "http://my.app/api/admin/users",
"per_page": 15,
"to": 15,
"total": 25
}
}
why laravel paginated responses have different JSON structure?
What does your UserCollection class look like?
At first glance, it looks like this is because the first method AdminUserController#index is converting the response to JSON, while the second method ClientUserController #index is returning a collection.

Spring pagination - request parameters

My REST contorller:
#GetMapping("/test")
public Page<MyObject> pathParamTest(Pageable pageable) {
return myService.getPage(pageable);
}
I send a request like following:
localhost:8091/endpoint/test?page=0&size=3&sort=id&direction=DESC
It's my response from server:
{
"content": [
{
"id": 1
},
{
"id": 2
},
{
"id": 3
}
],
"last": true,
"totalPages": 1,
"totalElements": 3,
"first": true,
"sort": [
{
"direction": "ASC",
"property": "id",
"ignoreCase": false,
"nullHandling": "NATIVE",
"descending": false,
"ascending": true
}
],
"numberOfElements": 3,
"size": 3,
"number": 0
}
but the request has still direction = ASC.
How can I send to server direction = DESC?
And why response has a field "last" = true, because next page has one element more?
try
localhost:8091/endpoint/test?page=0&size=3&sort=id,DESC
from spring data rest 6.2. Sorting
curl -v
"http://localhost:8080/people/search/nameStartsWith?name=K&sort=name,desc"
sort Properties that should be sorted by in the format
property,property(,ASC|DESC). Default sort direction is ascending. Use
multiple sort parameters if you want to switch directions, e.g.
?sort=firstname&sort=lastname,asc.

Resources