Pagination of API responses #601
Replies: 18 comments 34 replies
-
@yesoreyeram this looks pretty good and useful. Do you have any date in mind releasing this? Thanks! |
Beta Was this translation helpful? Give feedback.
-
The hard limit of 5 pages max is too low of a limit. Understand trying to protect the source however for large datasets more pages are required. |
Beta Was this translation helpful? Give feedback.
-
Hi , |
Beta Was this translation helpful? Give feedback.
-
I'm also facing the issue of the hard limit of 5 pages max is too low of a limit. The target API im using has a hard limit of 13 records (dont ask me why) and cant be changed by input. So in this case it will only pull 65 records what is to low because in my case there are more records to process. |
Beta Was this translation helpful? Give feedback.
-
Regarding the way of paging is working. I have some trouble te find out how to parse nested data when they are been paged. There seems is a differand behaver when the data is collected when using paging, and the inline option. So when the data is been loaded trough the api, and is paged, we have/see the data returned in the 5 rows. The nested data we want is that in "hits" from the api, there are 13 items in it. So now i will tell the plugin that the root is:
When i change it to: So i have striped down the json, create a array of 2 and use it as inline data: [{
"hits": [
{
"id": 1,
"provider": "x",
"description": "x",
"published": 1,
"properties": {
"A": true,
"B": true
},
"media": [
{
"id": "123",
"formats": {
"xxs": "xxs.jpg",
"xs": "xs.jpg"
},
"orientation": "landscape"
},
{
"id": "456",
"formats": {
"xxs": "xxs.jpg",
"xs": "xs.jpg"
},
"orientation": "landscape"
}
],
"location": {
"lat": "1.32",
"lon": "1.01"
},
"address": "x",
"agent": {
"id": 1,
"name": "x"
},
"city": "x",
"features": [],
"_id": "1",
"priceInfo": {
"price": "1.00"
},
"photo": {
"id": "123",
"formats": {
"xxs": "xxs.jpg",
"xs": "xs.jpg"
},
"type": 2,
"orientation": "landscape"
},
"link": "x"
},
{
"id": 2,
"provider": "x",
"description": "x",
"published": 1,
"properties": {
"A": true,
"B": true
},
"media": [
{
"id": "123",
"formats": {
"xxs": "xxs.jpg",
"xs": "xs.jpg"
},
"orientation": "landscape"
},
{
"id": "456",
"formats": {
"xxs": "xxs.jpg",
"xs": "xs.jpg"
},
"orientation": "landscape"
}
],
"location": {
"lat": "1.32",
"lon": "1.01"
},
"address": "x",
"agent": {
"id": 1,
"name": "x"
},
"city": "x",
"features": [],
"_id": "2",
"priceInfo": {
"price": "1.00"
},
"photo": {
"id": "123",
"formats": {
"xxs": "xxs.jpg",
"xs": "xs.jpg"
},
"type": 2,
"orientation": "landscape"
},
"link": "x"
}
],
"center": {
"lat": 1.87,
"lon": 1.45
},
"total": 87,
"pages": 7,
"page": 1,
"totalDisplay": 87,
"description": ""
},
{
"hits": [
{
"id": 3,
"provider": "x",
"description": "x",
"published": 1,
"properties": {
"A": true,
"B": true
},
"media": [
{
"id": "123",
"formats": {
"xxs": "xxs.jpg",
"xs": "xs.jpg"
},
"orientation": "landscape"
},
{
"id": "456",
"formats": {
"xxs": "xxs.jpg",
"xs": "xs.jpg"
},
"orientation": "landscape"
}
],
"location": {
"lat": "1.32",
"lon": "1.01"
},
"address": "x",
"agent": {
"id": 1,
"name": "x"
},
"city": "x",
"features": [],
"_id": "3",
"priceInfo": {
"price": "1.00"
},
"photo": {
"id": "123",
"formats": {
"xxs": "xxs.jpg",
"xs": "xs.jpg"
},
"type": 2,
"orientation": "landscape"
},
"link": "x"
},
{
"id": 4,
"provider": "x",
"description": "x",
"published": 1,
"properties": {
"A": true,
"B": true
},
"media": [
{
"id": "123",
"formats": {
"xxs": "xxs.jpg",
"xs": "xs.jpg"
},
"orientation": "landscape"
},
{
"id": "456",
"formats": {
"xxs": "xxs.jpg",
"xs": "xs.jpg"
},
"orientation": "landscape"
}
],
"location": {
"lat": "1.32",
"lon": "1.01"
},
"address": "x",
"agent": {
"id": 1,
"name": "x"
},
"city": "x",
"features": [],
"_id": "4",
"priceInfo": {
"price": "1.00"
},
"photo": {
"id": "123",
"formats": {
"xxs": "xxs.jpg",
"xs": "xs.jpg"
},
"type": 2,
"orientation": "landscape"
},
"link": "x"
}
],
"center": {
"lat": 1.87,
"lon": 1.45
},
"total": 87,
"pages": 7,
"page": 2,
"totalDisplay": 87,
"description": ""
}] Whenever i now apply the paring ps, after some hours debugging the json file , seems that there is a strange behaver of it and found that the items in {
"hits": [
{
"anumber": "",
"anumber_base": ""
},
{
"anumber": "121",
"anumber_base": 121
}
]
} |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Hello, your solution is great. |
Beta Was this translation helpful? Give feedback.
-
@yesoreyeram hello this is amazing stuff thank you for your work, i have a question thought. when using Iterating URLs in a loop is there a way to add the variable that i used to loop as a column to have that value in each row to know to which variable value it belongs to? |
Beta Was this translation helpful? Give feedback.
-
Hello, I solved pagination problem by adding multiple queries A,B,C for example. in A i used per_page=100 and number page_number 1 , for B per_page=100 and page_number 2. Then I merge using the transformation Merge by Id. I got all elements of page one and two in the same dashboard. This is without BACKEND parser, it works with UQL Thank you |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Correct me if I'm wrong, but I don't really understand the |
Beta Was this translation helpful? Give feedback.
-
This has been mentioned numerous times in this thread, but I also believe the '5 pages' limitation should be configurable. Even when examining Grafana's native APIs, such as the Grafana OnCall API, some routes return 50 records per page. The page size is not configurable. In my opinion, a limit of 250 records is far too conservative. |
Beta Was this translation helpful? Give feedback.
-
Check out the GitHub GraphQL API for an application in GraphQL for this. It might be nice to give the GraphQL mode access to pagination. |
Beta Was this translation helpful? Give feedback.
-
My eventual solution: Fivetran + neon postgresql database (both have a free tier) Works wonders |
Beta Was this translation helpful? Give feedback.
-
There are many cases where the API that's being called is an internal API so it should be down to the developer to choose what the max number of pages is, can the limit be removed from max pages? |
Beta Was this translation helpful? Give feedback.
-
Also facing the 5 pages limitation problem on an internal API. |
Beta Was this translation helpful? Give feedback.
-
Same problem with pagination. 5 is very very low |
Beta Was this translation helpful? Give feedback.
-
Background and current status of pagination feature ( Nov 2024 )Pagination feature was introduced in infinity backend parser an year ago as an experimental/beta/undocumented feature. As there are different types of pagination and much complexities behind handling them, still we aren't in a position to make it out of beta. The complexities include how to handle error in one of the pages, when to stop the pagination, how to handle partial data, how to handle no data vs error, how to stop racing condition, making parallel requests for paginated queries to improve the performance etc. Though this feature is in beta, We love the enthusiasm of the community who tried the pagination feature and providing continuous feedback and exploring the potentials of the infinity plugin. Maximum number of pages option & issues behindWhen the pagination feature was introduced, I strongly believed that getting paginated results in grafana is a unusual/unconventional use case. With Grafana's use cases user should query aggregated results instead of pulling every data and post processing/filtering/aggregation in the grafana where possible. Also loading large number of results with pagination into grafana's memory will put additional stress to grafana server. If one of the poor query triggers heavy pagination, it will affect all other grafana users in that instance. While considering the pagination, we do consider not only the requests coming from dashboards but also other cron jobs such as alerting, recorded queries etc. Increasing the max pagination will increase the grafana server memory/cpu in such cases as well. I agree that there are workarounds that a user can trigger multiple paginated queries via options such as repeat panel etc. That still doesn't justify the needs to increase the max pagination size. Path/Options forwardThough this is beta/experimental feature, we understand that pagination is important for many users and some use cases. Also removing the limitation on max pagination is also crucial for some users. Note We haven't ignored the option for max page customisation. Instead, we are exploring safer options such as setting the option via environment variable so that grafana admins can take informed decision about this configuration. This will also protect our grafana cloud and partner cloud hosted grafana environments. Also we have prioritised other important features such as supporting oAuth scenarios, making the backend parser as default, improving the documentation etc to make this plugin better. Also we are running low in bandwidth to implement/enhance the pagination. But we are open for enhancement once we have enough use case information around this. Looking for feedback & use-casesThe more use cases we can gather from the community, the better we are able to design and prioritise a solution for the pagination feature. Feel free to provide the use-cases and feedback in this discussion. |
Beta Was this translation helpful? Give feedback.
-
Available from: Infinity version 2.0.0
Supported types: JSON
Supported parsers: Backend
Pagination
When calling an API, if the underlying system have lots of results typically the server will send responses in multiple pages.
Pagination in Infinity
Introducing pagination of API response in Infinity 2.0. Prior to infinity version 2.0.0, you can only one page at a time. To call multiple pages and consolidate, you might be adding multiple queries manually and use merge transformation.
Types of Pagination
In the modern API world, pagination is implemented in different ways. Following are the common pagination mechanisms supported in infinity
Offset based pagination
TODO: yet to be documented
Page number based pagination
TODO: yet to be documented
Cursor based pagination
TODO: yet to be documented
Iterating URLs in a loop
Apart from the regular pagination methods mentioned above, From infinity 2.0, you have the ability to iterate the URLs based on comma separated values.
For example, we would like to call 3 different pokemons API items and show in a single result. We will be using following three URL.
As you see, we have three different URLs with 3 different paths. So I am going to to parameterise this as follows.
Now in the infinity pagination, I can instruct it to replace
{{ pokemon_name }}
part of the URL withbulbasaur,ivysaur,venusaur
. Under the hood, infinity will split the values by,
and then replace{{ pokemon_name }}
with each item in the list and make the API call.Below screenshot is an example of how to use it.
When used with dashboard variables, you can replace the hardcoded list of items to point a variable. Example: When you have a multi-value variable called
pokemon_id
, you can refer it as${pokemon_id:csv}
in the list value.Limitation
Number of maximum pages per query is limited to 5. This is to avoid resource exhaustion and DDOSing of the target system.
Beta Was this translation helpful? Give feedback.
All reactions