Changes in default limit values
All WEB3 API endpoints that support pagination will change the default page size from 500
to 100
.
Along with this, there will also be a fixed max limit of 100
(you can still select a lower limit than 100 if you wish).
What can break?
If your application relies on the default page size being 500 or if your explicit limit of the API calls are higher than 100, then your pagination logic might break.
What you need to do
If you rely on the assumption that the page size will be 500 if no limit is specified, you need to make changes to either fetch 5 pages (to get the same amount), or adjust the page size in your application.
See examples below:
Example: NodeJS SDK
The following example demonstrates a polyfill if your application needs to emulate a page size higher than 100
import Moralis from "moralis/node";
const serverUrl = "https://yoursubdomain.usemoralis.com:2053/server";
const appId = "yourAppId";
const contractAddress = "someContractAddress";
let owners: any
async function start(){
await Moralis.start({ serverUrl: serverUrl, appId: appId });
// Get first 500
await getOwners();
// Simulate old page size by dividing page by 5
console.log(Math.floor(owners.page / 5))
// Get next 500
await getOwners()
console.log(Math.floor(owners.page / 5))
}
async function includeNextNPages(previous: any, numPages: number){
// Define results for the remaining pages
const result = previous.result || [];
// Always keep the latest response around
let response = previous;
// Loop through the remaining pages
for (let i = 0; i < numPages; i++) {
// Get the next page
response = await response.next(); //Best Practice: Always use next() to get the next page
// Exit if we are on the last page already
if (response.result.length == 0) break
// Add the results to the previous results
result.push(...response.result);
}
// Apply the results to the last page
response.result = result
// Return the response
return response
}
async function getOwners() {
owners = await Moralis.Web3API.token.getNFTOwners({
address: contractAddress,
chain: "eth", // Best Practice: Always specify chain
limit: 100, // Best Practice: Always specify limit. (use the lowest limit you need for faster response)
cursor: owners ? owners.cursor : null, // Optional
}).then((response) => includeNextNPages(response, 4));
}
start()
Example: NodeJS API Calls
import axios from 'axios'
let owners: any
let cursor: string = '';
let page = 0;
const apiKey = 'youApiKey'
const contractAddress = "someContractAddress";
const url = `https://deep-index.moralis.io/api/v2/nft/${contractAddress}/owners?chain=eth&format=decimal&limit=100` // Best Practice: Always specify chain and limit
const options = { headers: { 'Accept': 'application/json', 'x-api-key': apiKey }}
async function fetchOwners() {
const response = await axios.get(`${url}${cursor.length > 0 ? `&cursor=${cursor}`: ''}`, options).then(response => response.data);
cursor = response.cursor;
return response;
}
async function getOwners() {
owners = await fetchOwners().then((response) => includeNextNPages(response, 4));
// Simulate old page size by dividing page by 5
page = Math.floor(owners.page / 5);
}
async function includeNextNPages(previous: any, numPages: number){
//Define results for the remaining pages
const result = previous.result || [];
// Always keep the latest response around
let response = previous;
// Loop through the remaining pages
for (let i = 0; i < numPages; i++) {
// Get the next page
response = await fetchOwners();
// Exit if we are on the last page already
if (response.result.length == 0) break
// Add the results to the previous results
result.push(...response.result);
}
// Apply the results to the last page
response.result = result
// Return the response
return response
}
async function start() {
// Get first 500
await getOwners();
console.log(page);
// Get next 500
await getOwners();
console.log(page);
}
start()
Changes in offset parameter
All WEB3 API endpoints that support cursor pagination will remove the possibility to use the offset
parameter as means of pagination.
What can break?
If your application uses offset
to implement pagination, you will have to refactor to use cursor pagination
instead.
If your application is build to be able to instantly “jump” to a page futher ahead, this will no longer be possible.
Instead you can work with other “constraints” to “jump ahead”. For example: many endpoints allows you to specify to_block
or to_date
. By using these you can “jump” ahead instead of using offset
What you need to do
If you are manually using offset to paginate and use the SDK, you can easily just switch to use next()
.
You can read more here: https://docs.moralis.io/moralis-dapp/web3-api#web3-api-pagination-examples-with-.next
If your application is built to be able to jump to a page further away, you need to work with constraints instead.
If you work with the API directly, you will need to work with cursor instead of offset.
You can read more about cursor here: https://docs.moralis.io/misc/rate-limit#example-of-how-to-use-cursor-nodejs
Best Practices in Pagination
- Always specify chain explicitly
- Always specify limit explicitly
- Use the smallest limit you need. i.e if you only display 20 items on a page, use 20 as limit
- Use constraints where you need. i.e if you are only interested in the NFT transfers of the latest week, use the from_date parameter to narrow down the result. this will decrease network traffic and lower response time.