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

Posted

技术标签:

【中文标题】如何为 Gatsby 页面查询创建自定义解析器?【英文标题】:How to create custom resolvers for Gatsby page queries? 【发布时间】:2021-10-14 09:51:24 【问题描述】:

我有一个 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 
    ]

这个盖茨比页面查询:


  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 字段设置为 @,我需要删除它987654330@.

我尝试将其插入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() 放入其中)。

如果公共字段设置为 false 或一般方向进入,如何删除 url 字段的任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

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

然后将您的 createResolvers 函数更新为如下内容:

exports.createResolvers = ( createResolvers ) => 
  createResolvers(
    SanityVideo: 
      safeUrl: 
        type: "String",
        resolve: (source, args, context, info) => source.public ? source.url : null
      ,
    ,
  )

    我不相信解析器可以替换模式起源的节点(字段),因此使用safeUrl 而不是url 要添加字段的类型是 SanityVideo,父节点是什么并不重要,这将适用于数据中 SanityVideo 的所有实例

【讨论】:

这确实是正确答案,谢谢@coreyward!

以上是关于如何为 Gatsby 页面查询创建自定义解析器?的主要内容,如果未能解决你的问题,请参考以下文章

如何为一组自定义分类页面创建可变页面标题

如何为计时时间戳使用自定义 serde 反序列化器?

如何为自定义帖子类型存档页面创建导航

如何为数组中的每个创建一个具有唯一图像和选择器的自定义 UIButton?

如何为文本输入创建逻辑布尔解析器?

如何为我的 Gatsby 网站创建第二个博客模板