From 647db5122e7b7be7f032d50ccf332780d8203369 Mon Sep 17 00:00:00 2001 From: Dan Ribbens Date: Wed, 16 Mar 2022 14:58:41 -0400 Subject: [PATCH] feat: add pagination argument to optimize graphql relationships and use in local api (#482) --- docs/local-api/overview.mdx | 1 + src/collections/operations/find.ts | 4 ++ src/collections/operations/local/find.ts | 3 + .../operations/local/local.spec.js | 66 +++++++++++++++++++ src/graphql/schema/buildObjectType.ts | 2 + 5 files changed, 76 insertions(+) diff --git a/docs/local-api/overview.mdx b/docs/local-api/overview.mdx index 2d51ce1382..13469b79a4 100644 --- a/docs/local-api/overview.mdx +++ b/docs/local-api/overview.mdx @@ -65,6 +65,7 @@ You can specify more options within the Local API vs. REST or GraphQL due to the | `overrideAccess` | Skip access control. By default, this property is set to false. | | `user` | If you re-enable access control, you can specify a user to use against the access control checks. | | `showHiddenFields` | Opt-in to receiving hidden fields. By default, they are hidden from returned documents in accordance to your config. | +| `pagination` | Set to false to return all documents and avoid querying for document counts. | *There are more options available on an operation by operation basis outlined below.* diff --git a/src/collections/operations/find.ts b/src/collections/operations/find.ts index 8d6dcc691e..3fc1472322 100644 --- a/src/collections/operations/find.ts +++ b/src/collections/operations/find.ts @@ -19,6 +19,7 @@ export type Arguments = { depth?: number req?: PayloadRequest overrideAccess?: boolean + pagination?: boolean showHiddenFields?: boolean draft?: boolean } @@ -55,6 +56,7 @@ async function find(incomingArgs: Arguments): Promis }, overrideAccess, showHiddenFields, + pagination = true, } = args; // ///////////////////////////////////// @@ -114,6 +116,8 @@ async function find(incomingArgs: Arguments): Promis lean: true, leanWithId: true, useEstimatedCount, + pagination, + useCustomCountFn: pagination ? undefined : () => Promise.resolve(1), }; const paginatedDocs = await Model.paginate(query, optionsToExecute); diff --git a/src/collections/operations/local/find.ts b/src/collections/operations/local/find.ts index 0fd4a9132a..430f4ef7dd 100644 --- a/src/collections/operations/local/find.ts +++ b/src/collections/operations/local/find.ts @@ -12,6 +12,7 @@ export type Options = { user?: Document overrideAccess?: boolean showHiddenFields?: boolean + pagination?: boolean sort?: string where?: Where draft?: boolean @@ -31,6 +32,7 @@ export default async function find(options: Options) showHiddenFields, sort, draft = false, + pagination = true, } = options; const collection = this.collections[collectionSlug]; @@ -45,6 +47,7 @@ export default async function find(options: Options) overrideAccess, showHiddenFields, draft, + pagination, req: { user, payloadAPI: 'local', diff --git a/src/collections/operations/local/local.spec.js b/src/collections/operations/local/local.spec.js index b08b793df8..be905729d1 100644 --- a/src/collections/operations/local/local.spec.js +++ b/src/collections/operations/local/local.spec.js @@ -117,5 +117,71 @@ describe('Collections - Local', () => { expect(relationshipBWithHiddenNestedField.post[0].demoHiddenField).toStrictEqual(demoHiddenField); }); + describe('Find', () => { + const title = 'local-find'; + beforeAll(async (done) => { + const data = { + title, + description: 'a description', + priority: 1, + nonLocalizedGroup: { + text: 'english', + }, + localizedGroup: { + text: 'english', + }, + nonLocalizedArray: [ + { + localizedEmbeddedText: 'english', + }, + ], + richTextBlocks: [ + { + blockType: 'richTextBlock', + blockName: 'Test Block Name', + content: [{ + children: [{ text: 'english' }], + }], + }, + ], + }; + await payload.create({ + collection: 'localized-posts', + data, + }); + Array.from(Array(10).keys()).map(async (i) => { + const uniqueTitle = `${title}-${i}`; + await payload.create({ + collection: 'localized-posts', + data: { + ...data, + title: uniqueTitle, + }, + }); + }); + done(); + }); + it('should find collection with query', async () => { + const result = await payload.find({ + collection: 'localized-posts', + where: { + title: { + equals: title, + }, + }, + }); + const doc = result.docs[0]; + expect(doc.id).toBeDefined(); + expect(doc.title).toStrictEqual(title); + }); + it('should allow disable pagination to return all docs', async () => { + const result = await payload.find({ + collection: 'localized-posts', + pagination: false, + limit: 5, // limit will not be used + }); + expect(result.docs.length).toBeGreaterThan(10); + }); + }); }); }); diff --git a/src/graphql/schema/buildObjectType.ts b/src/graphql/schema/buildObjectType.ts index 067c5154c8..4d1ff6643a 100644 --- a/src/graphql/schema/buildObjectType.ts +++ b/src/graphql/schema/buildObjectType.ts @@ -128,6 +128,7 @@ function buildObjectType(name: string, fields: Field[], parentName: string, base fallbackLocale, }, depth: 0, + pagination: false, }; const relatedDocument = await find(relatedDocumentQuery); @@ -291,6 +292,7 @@ function buildObjectType(name: string, fields: Field[], parentName: string, base fallbackLocale, }, depth: 0, + pagination: false, }); if (result.docs.length === 1) {