mirror of
https://github.com/strapi/strapi.git
synced 2025-10-29 00:49:49 +00:00
Implement pagination logic in core api
This commit is contained in:
parent
b44a552eee
commit
b781213b01
@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const { createService, getFetchParams } = require('../service');
|
||||
const { createService } = require('../service');
|
||||
|
||||
const maxLimit = 50;
|
||||
const defaultLimit = 20;
|
||||
@ -82,7 +82,7 @@ describe('Default Service', () => {
|
||||
await service.createOrUpdate(input);
|
||||
|
||||
expect(strapi.entityService.find).toHaveBeenCalledWith('testModel', {
|
||||
params: { publicationState: 'live', pagination: { limit: defaultLimit } },
|
||||
params: { publicationState: 'live' },
|
||||
});
|
||||
|
||||
expect(strapi.entityService.create).toHaveBeenCalledWith('testModel', { data: input });
|
||||
@ -111,7 +111,7 @@ describe('Default Service', () => {
|
||||
|
||||
expect(strapi.entityService.find).toHaveBeenCalledWith('testModel', {
|
||||
populate: undefined,
|
||||
params: { publicationState: 'live', pagination: { limit: defaultLimit } },
|
||||
params: { publicationState: 'live' },
|
||||
});
|
||||
|
||||
expect(strapi.entityService.update).toHaveBeenCalledWith('testModel', 1, {
|
||||
@ -138,7 +138,7 @@ describe('Default Service', () => {
|
||||
|
||||
expect(strapi.entityService.find).toHaveBeenCalledWith('testModel', {
|
||||
populate: undefined,
|
||||
params: { publicationState: 'live', pagination: { limit: defaultLimit } },
|
||||
params: { publicationState: 'live' },
|
||||
});
|
||||
|
||||
expect(strapi.entityService.delete).toHaveBeenCalledWith('testModel', 1);
|
||||
@ -146,36 +146,3 @@ describe('Default Service', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getFetchParams', () => {
|
||||
test.each([
|
||||
[`0 if limit is '0'`, { limit: '0', maxLimit }, 0],
|
||||
['0 if limit is 0', { limit: 0, maxLimit }, 0],
|
||||
[`0 if limit is ''`, { limit: '', maxLimit }, 0],
|
||||
[`1 if limit is '1'`, { limit: '1', maxLimit }, 1],
|
||||
[
|
||||
`${maxLimit} if limit(500) exceeds max allowed limit (${maxLimit})`,
|
||||
{ limit: '500', maxLimit },
|
||||
maxLimit,
|
||||
],
|
||||
[
|
||||
`${maxLimit} if limit is set to -1 and max allowed limit is set (${maxLimit})`,
|
||||
{ limit: '-1', maxLimit },
|
||||
maxLimit,
|
||||
],
|
||||
[`${defaultLimit} (default) if no limit is provided`, { maxLimit }, defaultLimit],
|
||||
[
|
||||
`${defaultLimit} (default) if limit is undefined`,
|
||||
{ limit: undefined, maxLimit },
|
||||
defaultLimit,
|
||||
],
|
||||
['1000 if limit=1000 and no max allowed limit is set', { limit: 1000 }, 1000],
|
||||
])('Sets limit parameter to %s', (description, input, expected) => {
|
||||
strapi.config.api.rest.maxLimit = input.maxLimit;
|
||||
expect(getFetchParams({ pagination: { limit: input.limit } })).toMatchObject({
|
||||
pagination: {
|
||||
limit: expected,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -8,10 +8,10 @@ const {
|
||||
} = require('@strapi/utils').contentTypes;
|
||||
|
||||
const {
|
||||
applyDefaultPagination,
|
||||
getPaginationInfo,
|
||||
convertPagedToStartLimit,
|
||||
shouldCount,
|
||||
formatPaginationResponse,
|
||||
transformPaginationResponse,
|
||||
} = require('./pagination');
|
||||
|
||||
const setPublishedAt = data => {
|
||||
@ -31,7 +31,7 @@ const createCollectionTypeService = ({ model, strapi, utils }) => {
|
||||
async find(opts = {}) {
|
||||
const params = getFetchParams(opts.params);
|
||||
|
||||
const paginationInfo = applyDefaultPagination(params);
|
||||
const paginationInfo = getPaginationInfo(params);
|
||||
|
||||
const results = await strapi.entityService.find(uid, {
|
||||
params: { ...params, ...convertPagedToStartLimit(paginationInfo) },
|
||||
@ -44,7 +44,7 @@ const createCollectionTypeService = ({ model, strapi, utils }) => {
|
||||
|
||||
return {
|
||||
results,
|
||||
pagination: formatPaginationResponse(paginationInfo, count),
|
||||
pagination: transformPaginationResponse(paginationInfo, count),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const { has, toNumber, isUndefined, isPlainObject } = require('lodash/fp');
|
||||
|
||||
/**
|
||||
* Default limit values from config
|
||||
* @return {{maxLimit: number, defaultLimit: number}}
|
||||
*/
|
||||
const getLimitConfigDefaults = () => ({
|
||||
defaultLimit: _.toNumber(strapi.config.get('api.rest.defaultLimit', 25)),
|
||||
maxLimit: _.toNumber(strapi.config.get('api.rest.maxLimit')) || null,
|
||||
defaultLimit: toNumber(strapi.config.get('api.rest.defaultLimit', 25)),
|
||||
maxLimit: toNumber(strapi.config.get('api.rest.maxLimit')) || null,
|
||||
});
|
||||
|
||||
/**
|
||||
@ -33,10 +34,13 @@ const shouldCount = params => {
|
||||
return Boolean(strapi.config.get('api.rest.withCount', true));
|
||||
};
|
||||
|
||||
const applyDefaultPagination = params => {
|
||||
const isOffsetPagination = pagination => has('start', pagination) || has('limit', pagination);
|
||||
const isPagedPagination = pagination => has('page', pagination) || has('page', pagination);
|
||||
|
||||
const getPaginationInfo = params => {
|
||||
const { defaultLimit, maxLimit } = getLimitConfigDefaults();
|
||||
|
||||
if (_.isUndefined(params.pagination) || !_.isPlainObject(params.pagination)) {
|
||||
if (isUndefined(params.pagination) || !isPlainObject(params.pagination)) {
|
||||
return {
|
||||
start: 0,
|
||||
limit: defaultLimit,
|
||||
@ -45,23 +49,27 @@ const applyDefaultPagination = params => {
|
||||
|
||||
const { pagination } = params;
|
||||
|
||||
if (!_.isUndefined(pagination.pageSize) || !_.isUndefined(pagination.page)) {
|
||||
const pageSize = _.isUndefined(pagination.pageSize)
|
||||
if (isOffsetPagination(pagination) && isPagedPagination(pagination)) {
|
||||
throw new Error('Invalid pagination parameters. Expected either start/limit or page/pageSize');
|
||||
}
|
||||
|
||||
if (isPagedPagination(pagination)) {
|
||||
const pageSize = isUndefined(pagination.pageSize)
|
||||
? defaultLimit
|
||||
: Math.max(1, _.toNumber(pagination.pageSize));
|
||||
: Math.max(1, toNumber(pagination.pageSize));
|
||||
|
||||
return {
|
||||
page: Math.max(1, _.toNumber(pagination.page || 1)),
|
||||
page: Math.max(1, toNumber(pagination.page || 1)),
|
||||
pageSize: applyMaxLimit(pageSize, maxLimit),
|
||||
};
|
||||
}
|
||||
|
||||
const limit = _.isUndefined(pagination.limit)
|
||||
const limit = isUndefined(pagination.limit)
|
||||
? defaultLimit
|
||||
: Math.max(1, _.toNumber(pagination.limit));
|
||||
: Math.max(1, toNumber(pagination.limit));
|
||||
|
||||
return {
|
||||
start: Math.max(0, _.toNumber(pagination.start || 0)),
|
||||
start: Math.max(0, toNumber(pagination.start || 0)),
|
||||
limit: applyMaxLimit(limit, maxLimit),
|
||||
};
|
||||
};
|
||||
@ -78,7 +86,7 @@ const convertPagedToStartLimit = pagination => {
|
||||
return pagination;
|
||||
};
|
||||
|
||||
const formatPaginationResponse = (paginationInfo, count) => {
|
||||
const transformPaginationResponse = (paginationInfo, count) => {
|
||||
if (paginationInfo.page) {
|
||||
return {
|
||||
...paginationInfo,
|
||||
@ -94,8 +102,8 @@ const formatPaginationResponse = (paginationInfo, count) => {
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
applyDefaultPagination,
|
||||
getPaginationInfo,
|
||||
convertPagedToStartLimit,
|
||||
transformPaginationResponse,
|
||||
shouldCount,
|
||||
formatPaginationResponse,
|
||||
};
|
||||
|
||||
@ -61,6 +61,7 @@ module.exports = strapi => {
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user