feat: add find to payloadDataLoader to cache local API queries (#11685)
### What?
Extends our dataloader to add a momiozed payload find function. This way
it will cache the query for the same find request using a cacheKey from
find operation args.
### Why?
This was needed internally for `filterOptions` that exist in an array or
other sitautions where you have the same exact query being made and
awaited many times.
### How?
- Added `find` to payloadDataLoader. Marked `@experimental` in case it
needs to change.
- Created a cache key from the args
- Validate filterOptions changed from `payload.find` to
`payloadDataLoader.find`
- Made `payloadDataLoader` no longer optional on `PayloadRequest`, since
other args are required which are created from createLocalReq (context
for example), I don't see a reason why dataLoader shouldn't be required
also.
Example usage:
```ts
const result = await req.payloadDataLoader.find({
collection,
req,
where,
})
```
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
/* eslint-disable jest/require-top-level-describe */
|
||||
import { PostgresAdapter } from '@payloadcms/db-postgres/types'
|
||||
import type { PostgresAdapter } from '@payloadcms/db-postgres/types'
|
||||
|
||||
import { cosineDistance, desc, gt, sql } from 'drizzle-orm'
|
||||
import path from 'path'
|
||||
import { buildConfig, getPayload } from 'payload'
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { Payload } from 'payload'
|
||||
import type { CollectionSlug, Payload } from 'payload'
|
||||
|
||||
import path from 'path'
|
||||
import { createLocalReq } from 'payload'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import type { NextRESTClient } from '../helpers/NextRESTClient.js'
|
||||
@@ -28,7 +29,9 @@ describe('dataloader', () => {
|
||||
},
|
||||
})
|
||||
|
||||
if (loginResult.token) token = loginResult.token
|
||||
if (loginResult.token) {
|
||||
token = loginResult.token
|
||||
}
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
@@ -187,4 +190,26 @@ describe('dataloader', () => {
|
||||
expect(innerMostRelationship).toStrictEqual(relationB.id)
|
||||
})
|
||||
})
|
||||
|
||||
describe('find', () => {
|
||||
it('should call the same query only once in a request', async () => {
|
||||
const req = await createLocalReq({}, payload)
|
||||
const spy = jest.spyOn(payload, 'find')
|
||||
|
||||
const findArgs = {
|
||||
collection: 'items' as CollectionSlug,
|
||||
req,
|
||||
depth: 0,
|
||||
where: {
|
||||
name: { exists: true },
|
||||
},
|
||||
}
|
||||
|
||||
void req.payloadDataLoader.find(findArgs)
|
||||
void req.payloadDataLoader.find(findArgs)
|
||||
await req.payloadDataLoader.find(findArgs)
|
||||
|
||||
expect(spy).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user