feat: select fields (#8550)
Adds `select` which is used to specify the field projection for local and rest API calls. This is available as an optimization to reduce the payload's of requests and make the database queries more efficient. Includes: - [x] generate types for the `select` property - [x] infer the return type by `select` with 2 modes - include (`field: true`) and exclude (`field: false`) - [x] lots of integration tests, including deep fields / localization etc - [x] implement the property in db adapters - [x] implement the property in the local api for most operations - [x] implement the property in the rest api - [x] docs --------- Co-authored-by: Dan Ribbens <dan.ribbens@gmail.com>
This commit is contained in:
99
docs/queries/select.mdx
Normal file
99
docs/queries/select.mdx
Normal file
@@ -0,0 +1,99 @@
|
||||
---
|
||||
title: Select
|
||||
label: Select
|
||||
order: 30
|
||||
desc: Payload select determines which fields are selected to the result.
|
||||
keywords: query, documents, pagination, documentation, Content Management System, cms, headless, javascript, node, react, nextjs
|
||||
---
|
||||
|
||||
You may not need the full data from your Local API / REST queries, but only some specific fields. The select fields API can help you to optimize those cases.
|
||||
|
||||
## Local API
|
||||
|
||||
To specify select in the [Local API](../local-api/overview), you can use the `select` option in your query:
|
||||
|
||||
```ts
|
||||
// Include mode
|
||||
const getPosts = async () => {
|
||||
const posts = await payload.find({
|
||||
collection: 'posts',
|
||||
select: {
|
||||
text: true,
|
||||
// select a specific field from group
|
||||
group: {
|
||||
number: true
|
||||
},
|
||||
// select all fields from array
|
||||
array: true,
|
||||
}, // highlight-line
|
||||
})
|
||||
|
||||
return posts
|
||||
}
|
||||
|
||||
// Exclude mode
|
||||
const getPosts = async () => {
|
||||
const posts = await payload.find({
|
||||
collection: 'posts',
|
||||
// Select everything except for array and group.number
|
||||
select: {
|
||||
array: false,
|
||||
group: {
|
||||
number: false
|
||||
}
|
||||
}, // highlight-line
|
||||
})
|
||||
|
||||
return posts
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
<Banner type="warning">
|
||||
<strong>Important:</strong>
|
||||
To perform querying with `select` efficiently, it works on the database level. Because of that, your `beforeRead` and `afterRead` hooks may not receive the full `doc`.
|
||||
</Banner>
|
||||
|
||||
|
||||
## REST API
|
||||
|
||||
To specify select in the [REST API](../rest-api/overview), you can use the `select` parameter in your query:
|
||||
|
||||
```ts
|
||||
fetch('https://localhost:3000/api/posts?select[color]=true&select[group][number]=true') // highlight-line
|
||||
.then((res) => res.json())
|
||||
.then((data) => console.log(data))
|
||||
```
|
||||
|
||||
To understand the syntax, you need to understand that complex URL search strings are parsed into a JSON object. This one isn't too bad, but more complex queries get unavoidably more difficult to write.
|
||||
|
||||
For this reason, we recommend to use the extremely helpful and ubiquitous [`qs`](https://www.npmjs.com/package/qs) package to parse your JSON / object-formatted queries into query strings:
|
||||
|
||||
```ts
|
||||
import { stringify } from 'qs-esm'
|
||||
|
||||
const select = {
|
||||
text: true,
|
||||
group: {
|
||||
number: true
|
||||
}
|
||||
// This query could be much more complex
|
||||
// and QS would handle it beautifully
|
||||
}
|
||||
|
||||
const getPosts = async () => {
|
||||
const stringifiedQuery = stringify(
|
||||
{
|
||||
select, // ensure that `qs` adds the `select` property, too!
|
||||
},
|
||||
{ addQueryPrefix: true },
|
||||
)
|
||||
|
||||
const response = await fetch(`http://localhost:3000/api/posts${stringifiedQuery}`)
|
||||
// Continue to handle the response below...
|
||||
}
|
||||
|
||||
<Banner type="info">
|
||||
<strong>Reminder:</strong>
|
||||
This is the same for [Globals](../configuration/globals) using the `/api/globals` endpoint.
|
||||
</Banner>
|
||||
Reference in New Issue
Block a user