From 8d63d4a9c891b240bad169efb86069497f64f2e6 Mon Sep 17 00:00:00 2001 From: Cody Olsen Date: Fri, 2 Jun 2023 08:45:18 +0200 Subject: [PATCH] fix(docs): add `perspective` documentation Co-Authored-By: Martin Jacobsen <174970+mmgj@users.noreply.github.com> --- README.md | 148 ++++++++++++++++++++++++++++++++++++++++ src/data/dataMethods.ts | 2 +- src/types.ts | 7 +- 3 files changed, 155 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 25579efa..ddcbd689 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,9 @@ export async function updateDocumentTitle(_id, title) { - [UMD](#umd) - [Specifying API version](#specifying-api-version) - [Performing queries](#performing-queries) + - [Using perspectives](#using-perspectives) + - [`published`](#published) + - [`previewDrafts`](#previewdrafts) - [Fetching Content Source Maps](#fetching-content-source-maps) - [Listening to queries](#listening-to-queries) - [Fetch a single document](#fetch-a-single-document) @@ -405,6 +408,151 @@ client.fetch(query, params).then((bikes) => { Perform a query using the given parameters (if any). +### Using perspectives + +The `perspective` option can be used to specify special filtering behavior for queries. The default value is `raw`, which means no special filtering is applied, while [`published`](#published) and [`previewDrafts`](#previewdrafts) can be used to optimize for specific use cases. + +#### `published` + +Useful for when you want to be sure that draft documents are not returned in production. Pairs well with private datasets. + +With a dataset that looks like this: + +```json +[ + { + "_type": "author", + "_id": "ecfef291-60f0-4609-bbfc-263d11a48c43", + "name": "George Martin" + }, + { + "_type": "author", + "_id": "drafts.ecfef291-60f0-4609-bbfc-263d11a48c43", + "name": "George R.R. Martin" + }, + { + "_type": "author", + "_id": "drafts.f4898efe-92c4-4dc0-9c8c-f7480aef17e2", + "name": "Stephen King" + } +] +``` + +And a query like this: + +```ts +import {createClient} from '@sanity/client' + +const client = createClient({ + ...config, + useCdn: true, // set to `false` to bypass the edge cache + perspective: 'published', +}) + +const authors = await client.fetch('*[_type == "author"]') +``` + +Then `authors` will only contain documents that don't have a `drafts.` prefix in their `_id`, in this case just "George Martin": + +```json +[ + { + "_type": "author", + "_id": "ecfef291-60f0-4609-bbfc-263d11a48c43", + "name": "George Martin" + } +] +``` + +#### `previewDrafts` + +Designed to help answer the question "What is our app going to look like after all the draft documents are published?". + +Given a dataset like this: + +```json +[ + { + "_type": "author", + "_id": "ecfef291-60f0-4609-bbfc-263d11a48c43", + "name": "George Martin" + }, + { + "_type": "author", + "_id": "drafts.ecfef291-60f0-4609-bbfc-263d11a48c43", + "name": "George R.R. Martin" + }, + { + "_type": "author", + "_id": "f4898efe-92c4-4dc0-9c8c-f7480aef17e2", + "name": "Stephen King" + } +] +``` + +And a query like this: + +```ts +import {createClient} from '@sanity/client' + +const client = createClient({ + ...config, + useCdn: false, // the `previewDrafts` perspective requires this to be `false` + perspective: 'previewDrafts', +}) + +const authors = await client.fetch('*[_type == "author"]') +``` + +Then `authors` will look like this. Note that the result dedupes documents with a preference for the draft version: + +```json +[ + { + "_type": "author", + "_id": "ecfef291-60f0-4609-bbfc-263d11a48c43", + "_originalId": "drafts.ecfef291-60f0-4609-bbfc-263d11a48c43", + "name": "George R.R. Martin" + }, + { + "_type": "author", + "_id": "f4898efe-92c4-4dc0-9c8c-f7480aef17e2", + "_originalId": "f4898efe-92c4-4dc0-9c8c-f7480aef17e2", + "name": "Stephen King" + } +] +``` + +Since the query simulates what the result will be after publishing the drafts, the `_id` doesn't contain the `drafts.` prefix. If you want to check if a document is a draft or not you can use the `_originalId` field, which is only available when using the `previewDrafts` perspective. + +```ts +const authors = await client.fetch(`*[_type == "author"]{..., "status": select( + _originalId in path("drafts.**") => "draft", + "published" +)}`) +``` + +Which changes the result to be: + +```json +[ + { + "_type": "author", + "_id": "ecfef291-60f0-4609-bbfc-263d11a48c43", + "_originalId": "drafts.ecfef291-60f0-4609-bbfc-263d11a48c43", + "name": "George R.R. Martin", + "status": "draft" + }, + { + "_type": "author", + "_id": "f4898efe-92c4-4dc0-9c8c-f7480aef17e2", + "_originalId": "f4898efe-92c4-4dc0-9c8c-f7480aef17e2", + "name": "Stephen King", + "status": "published" + } +] +``` + ### Fetching Content Source Maps Content Source Maps annotate fragments in your query results with metadata about its origin: the field, document, and dataset it originated from. diff --git a/src/data/dataMethods.ts b/src/data/dataMethods.ts index af0c6527..c6a8301d 100644 --- a/src/data/dataMethods.ts +++ b/src/data/dataMethods.ts @@ -307,7 +307,7 @@ export function _requestObservable( if (config.resultSourceMap) { options.query = {resultSourceMap: true, ...options.query} } - if (typeof config.perspective === 'string' && config.perspective !== 'all') { + if (typeof config.perspective === 'string' && config.perspective !== 'raw') { options.query = {perspective: config.perspective, ...options.query} } } diff --git a/src/types.ts b/src/types.ts index 158ef735..f1204c65 100644 --- a/src/types.ts +++ b/src/types.ts @@ -35,7 +35,8 @@ export interface ClientConfig { /** @defaultValue true */ useCdn?: boolean token?: string - perspective?: 'previewDrafts' | 'published' | 'all' + /** @defaultValue 'raw' */ + perspective?: 'previewDrafts' | 'published' | 'raw' apiHost?: string apiVersion?: string proxy?: string @@ -193,6 +194,10 @@ export type SanityDocument = Record> _type: string _createdAt: string _updatedAt: string + /** + * Present when `perspective` is set to `previewDrafts` + */ + _originalId?: string } /** @internal */