That simple question should have a lot of answers.
Strapi does not recommand to do that - it might be heavy if you have a lot of records.
Anyway, a lot of users do need it.
Here’s my solution. In this example, the content type is area.
I override the find function in the controller.
If the query has its parameter pagination.page=-1, it’s a flag that we want ALL the records.
This solution is handly because you don’t need to create an extra route (eg. api/area/all), but you could if you want: the main idea is that we have a new service method findAll.
src/api/area/services/area.ts :
import { fetchAllEntries } from '../../../utils/fetchAllEntries'
export default factories.createCoreService('api::area.area', ({strapi}) => ({
async find(params) {
//get ALL items
if (params?.pagination?.page === '-1') {
return this.findAll(params);
}
// Calling the default core controller
return await super.find(params);
},
async findAll(params) {
return fetchAllEntries('api::area.area',params);
},
Rather than overriding the find method in the service, I would prefer use a middleware for this, but well, I haven’t find a way to achieve it.
src/utils/fetchAllEntries.ts:
export async function fetchAllEntries(type, query:any = {}) {
const maxLimit = strapi.config.get('api.rest.maxLimit', 25);
let allItems = [];
let iterations = 0;
let totalPages = 1;
let pagination = {} as any;
//If pagination was set
delete query.pagination;
do {
// Fetch entries with pagination
const response = await strapi.service(type).find({
...query,
pagination:{
page:iterations+1,
pageSize:maxLimit
}
});
allItems = [...allItems, ...response.results];
if (response.pagination){
pagination = {...response.pagination};
totalPages = pagination.pageCount;
}
console.info(`fetchAllEntries ${type}... ${iterations+1}/${pagination.pageCount}`);
iterations++;
} while (iterations < totalPages);
delete pagination.page;//we'll return all results so page is not a relevant info
return {
results:allItems,
pagination:pagination
};
}