如何为 Gatsby 页面查询创建自定义解析器?
How to create custom resolvers for Gatsby page queries?
我有一个 Gatsby 应用程序从 Sanity 中提取数据。
这是 course.js
:
的 Sanity 架构
import video from './video'
export default {
// Computer name
name: `courses`,
// Visible title
title: `Courses`,
type: `document`,
fields: [
{
name: `title`,
title: `Course title`,
type: `string`,
description: `Name of the course`
},
{
name: `slug`,
title: `slug`,
type: `slug`,
options: {
source: `title`,
maxLength: 100,
}
},
{
name: `price`,
title: `Price`,
type: `number`
},
{
name: `thumbnail`,
title: `Thumbnail`,
type: `image`,
options: {
hotspot: true,
}
},
{
name: `playlist`,
title: `Playlist`,
type: `array`,
of: [
{
title: `Video`,
name: `video`,
type: `video`,
}
]
},
]
}
这是 video.js
的 Sanity 架构:
export default {
// Computer name
name: `video`,
// Visible title
title: `Video`,
type: `object`,
fields: [
{ name: `title`, type: `string`, title: `Video title` },
{ name: `url`, type: `url`, title: `URL` },
{ name: `public`, title: `public`, type: `boolean`, initialValue: false }
]
}
这个Gatsby页面查询:
{
allSanityCourses {
nodes {
title
price
playlist {
url
title
public
}
}
}
}
结果:
{
"data": {
"allSanityCourses": {
"nodes": [
{
"title": "Master VS Code",
"price": 149,
"playlist": [
{
"url": "https://www.youtube.com/watch?v=PRz1Nv9GUzs",
"title": "Introduction",
"public": true
},
{
"url": "https://www.youtube.com/watch?v=PRz1Nv9GUzs",
"title": "Philosophy",
"public": false
},
{
"url": "https://www.youtube.com/watch?v=PRz1Nv9GUzs",
"title": "Tech and Tools",
"public": false
},
{
"url": "https://www.youtube.com/watch?v=PRz1Nv9GUzs",
"title": "Integration",
"public": true
},
{
"url": "https://www.youtube.com/watch?v=PRz1Nv9GUzs",
"title": "Extensions",
"public": false
}
]
}
]
}
},
"extensions": {}
}
为了防止 url
字段被注入运行此 Gatsby 页面查询的 React 组件(因为这些 urls
是付费的),我需要删除它,如果 public
字段设置为 false
.
我试过将其插入 gastby-node.js
:
exports.createSchemaCustomization = ({ actions, schema }) => {
const { createTypes } = actions
const typeDefs = [
schema.buildObjectType({
name: "SanityCourses",
fields: {
playlist: {
type: "[SanityVideo]",
url: {
type: "String",
resolve: (source) => "nope"
},
},
},
interfaces: ["Node"],
}),
]
createTypes(typeDefs)
}
并且:
exports.createResolvers = ({ createResolvers }) => {
const resolvers = {
SanityCourses: {
playlist: {
type: "[SanityVideo]",
url: {
type: "String",
resolve(source, args, context, info) {
return "nope"
},
}
},
},
}
createResolvers(resolvers)
}
但这两个似乎都不起作用。 url
字段 returns url 一如既往。解析器甚至似乎都没有触发(我试过将 console.log() 放入其中)。
如果 public 字段设置为 false,或提供有关如何删除 url 字段的任何帮助,我们将不胜感激。
放弃 createSchemaCustomization
中的尝试,因为您不需要在此处自定义架构(尽管我相信有一种方法可以使用它来实现您想要的,但预计其中的数据不会来自现有节点,这种未声明的依赖关系会产生缓存问题。
然后将您的 createResolvers
函数更新为如下内容:
exports.createResolvers = ({ createResolvers }) => {
createResolvers({
SanityVideo: {
safeUrl: {
type: "String",
resolve: (source, args, context, info) => source.public ? source.url : null
},
},
})
}
- 我不相信解析器可以替换源自模式的节点(字段),因此使用
safeUrl
而不是 url
- 您要添加字段的类型是
SanityVideo
,父节点是什么并不重要——这将应用于数据中 SanityVideo
的所有实例
我有一个 Gatsby 应用程序从 Sanity 中提取数据。
这是 course.js
:
import video from './video'
export default {
// Computer name
name: `courses`,
// Visible title
title: `Courses`,
type: `document`,
fields: [
{
name: `title`,
title: `Course title`,
type: `string`,
description: `Name of the course`
},
{
name: `slug`,
title: `slug`,
type: `slug`,
options: {
source: `title`,
maxLength: 100,
}
},
{
name: `price`,
title: `Price`,
type: `number`
},
{
name: `thumbnail`,
title: `Thumbnail`,
type: `image`,
options: {
hotspot: true,
}
},
{
name: `playlist`,
title: `Playlist`,
type: `array`,
of: [
{
title: `Video`,
name: `video`,
type: `video`,
}
]
},
]
}
这是 video.js
的 Sanity 架构:
export default {
// Computer name
name: `video`,
// Visible title
title: `Video`,
type: `object`,
fields: [
{ name: `title`, type: `string`, title: `Video title` },
{ name: `url`, type: `url`, title: `URL` },
{ name: `public`, title: `public`, type: `boolean`, initialValue: false }
]
}
这个Gatsby页面查询:
{
allSanityCourses {
nodes {
title
price
playlist {
url
title
public
}
}
}
}
结果:
{
"data": {
"allSanityCourses": {
"nodes": [
{
"title": "Master VS Code",
"price": 149,
"playlist": [
{
"url": "https://www.youtube.com/watch?v=PRz1Nv9GUzs",
"title": "Introduction",
"public": true
},
{
"url": "https://www.youtube.com/watch?v=PRz1Nv9GUzs",
"title": "Philosophy",
"public": false
},
{
"url": "https://www.youtube.com/watch?v=PRz1Nv9GUzs",
"title": "Tech and Tools",
"public": false
},
{
"url": "https://www.youtube.com/watch?v=PRz1Nv9GUzs",
"title": "Integration",
"public": true
},
{
"url": "https://www.youtube.com/watch?v=PRz1Nv9GUzs",
"title": "Extensions",
"public": false
}
]
}
]
}
},
"extensions": {}
}
为了防止 url
字段被注入运行此 Gatsby 页面查询的 React 组件(因为这些 urls
是付费的),我需要删除它,如果 public
字段设置为 false
.
我试过将其插入 gastby-node.js
:
exports.createSchemaCustomization = ({ actions, schema }) => {
const { createTypes } = actions
const typeDefs = [
schema.buildObjectType({
name: "SanityCourses",
fields: {
playlist: {
type: "[SanityVideo]",
url: {
type: "String",
resolve: (source) => "nope"
},
},
},
interfaces: ["Node"],
}),
]
createTypes(typeDefs)
}
并且:
exports.createResolvers = ({ createResolvers }) => {
const resolvers = {
SanityCourses: {
playlist: {
type: "[SanityVideo]",
url: {
type: "String",
resolve(source, args, context, info) {
return "nope"
},
}
},
},
}
createResolvers(resolvers)
}
但这两个似乎都不起作用。 url
字段 returns url 一如既往。解析器甚至似乎都没有触发(我试过将 console.log() 放入其中)。
如果 public 字段设置为 false,或提供有关如何删除 url 字段的任何帮助,我们将不胜感激。
放弃 createSchemaCustomization
中的尝试,因为您不需要在此处自定义架构(尽管我相信有一种方法可以使用它来实现您想要的,但预计其中的数据不会来自现有节点,这种未声明的依赖关系会产生缓存问题。
然后将您的 createResolvers
函数更新为如下内容:
exports.createResolvers = ({ createResolvers }) => {
createResolvers({
SanityVideo: {
safeUrl: {
type: "String",
resolve: (source, args, context, info) => source.public ? source.url : null
},
},
})
}
- 我不相信解析器可以替换源自模式的节点(字段),因此使用
safeUrl
而不是url
- 您要添加字段的类型是
SanityVideo
,父节点是什么并不重要——这将应用于数据中SanityVideo
的所有实例