如何为Gatsby页面查询创建自定义解析器?



我有一个从Sanity提取数据的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`,
}
]
},
]
}

这是Sanity对于video.js的schema:

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 }
]
}

This Gatsby page query:

{
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字段被注入到这个盖茨比页面查询运行的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字段一如既往地返回url。解析器甚至似乎都不会触发(我已经尝试将console.log()放入其中)。

关于如何删除url字段,如果公共字段设置为false,或一般方向去,将非常感谢任何帮助。

放弃createSchemaCustomization中的尝试,因为您不需要在这里自定义模式(尽管我相信有一种方法可以使用它实现您想要的功能,但不期望其中的数据来自现有节点,并且这种未声明的依赖关系可能会产生缓存问题)。

然后更新你的createResolvers函数如下:

exports.createResolvers = ({ createResolvers }) => {
createResolvers({
SanityVideo: {
safeUrl: {
type: "String",
resolve: (source, args, context, info) => source.public ? source.url : null
},
},
})
}
  1. 我不相信解析器可以取代模式生成的节点(字段),因此使用safeUrl代替url
  2. 您添加字段的类型是SanityVideo,无论父节点是什么-这将适用于您的数据中SanityVideo的所有实例

最新更新