如何给Gatsby提供GraphQL模式 [英] How to give Gatsby a GraphQL schema

查看:47
本文介绍了如何给Gatsby提供GraphQL模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们从Wordpress后端引入了一些帖子,一些带有图片(在ACF字段中),有些则没有.问题在于,盖茨比根据接收到的第一个节点来推断模式.如果它接收到没有图片的节点,则说明架构是错误的.

We're bringing in some posts from a Wordpress backend, some have pictures (in an ACF field) and some don't. The problem is that Gatsby infers the schema based off of the first node it receives. If it receives a node without a picture, then the schema is wrong.

盖茨比的位置GraphQL模式来自何处?通过Gatsby,我们使用了从不同来源获取数据的插件.然后,我们使用该数据自动推断GraphQL模式.

Where does Gatsby’s GraphQL schema come from? With Gatsby, we use plugins which fetch data from different sources. We then use that data to automatically infer a GraphQL schema.

我们如何为GraphQL/Gatsby指示一个始终包含图片的模式,如果空白,则将'null'作为默认值?

How can we dictate a schema to GraphQL/Gatsby that always includes a picture, with 'null' as the default value if it's blank?

{
  allWordpressWpTestimonial {
    edges {
      node {
        id
        title
        acf {
          photo_fields {
            photo {
              id
              localFile {
                childImageSharp {
                  sizes {
                    src
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

在上面的示例中,有时照片"不存在,并且会破坏所有内容...

In the example above, sometimes 'photo' doesn't exist and it breaks everything...

Gatsby配置:

const innertext = require('innertext')
const url = require('url')

module.exports = {
  siteMetadata: {
    title: 'Test',
    googleMapsAPIKey: 'xxxxxx',
    adminBaseUrl: '123.123.123',
    adminProtocol: 'http',
  },
  pathPrefix: '/web/beta',
  plugins: [
    'gatsby-plugin-react-next',
    'gatsby-plugin-react-helmet',
    'gatsby-plugin-sharp',
    'gatsby-plugin-svgr',
    {
      resolve: 'gatsby-plugin-google-analytics',
      options: {
        trackingId: 'GOOGLE_ANALYTICS_TRACKING_ID',
      },
    },
    {
      resolve: 'gatsby-plugin-bugherd',
      options: {
        key: 'xxxxxx',
        showInProduction: true,
      },
    },
    {
      resolve: '@andrew-codes/gatsby-plugin-elasticlunr-search',
      options: {
        fields: ['title', 'url', 'textContent', 'urlSearchable'],
        resolvers: {
          wordpress__PAGE: {
            title: node => node.title,
            textContent: node => innertext(node.content),
            url: node => url.parse(node.link).path,
            urlSearchable: node =>
              url
                .parse(node.link)
                .path.split('/')
                .join(' '),
          },
          wordpress__POST: {
            title: node => node.title,
            textContent: node => innertext(node.content),
            url: node => `/news/${node.slug}`,
            urlSearchable: node =>
              url
                .parse(node.link)
                .path.split('/')
                .join(' '),
          },
          wordpress__wp_industry: {
            title: node => node.title,
            textContent: node => innertext(node.content),
            url: node => `/business/industries/${node.slug}`,
            urlSearchable: node =>
              url
                .parse(node.link)
                .path.split('/')
                .join(' '),
          },
        },
      },
    },
    {
      resolve: 'gatsby-source-wordpress',
      options: {
        baseUrl: 'xxxxxx',
        protocol: 'http',
        hostingWPCOM: false,
        useACF: true,
        auth: {
          htaccess_user: 'admin',
          htaccess_pass: 'xxxxxx',
          htaccess_sendImmediately: false,
        },
        verboseOutput: false,
      },
    },
    'gatsby-transformer-sharp',
  ],
}

推荐答案

自这篇文章发布已经有一段时间了,但是自2.2版本以来

It's been awhile since this post, but since version 2.2 Gatsby has added a new API that'll make it much easier to customize schema. This is not an example with wordpress but with gatsby's gatsby-transformer-remark, but I'm sure it's applicable.

我有一堆 .md 像这样:

---
title: "Screen title"
image: "./hero-image.png"  <--- sometimes it's an empty string, ""
category: "Cat"
---

...content...

如果Gatsby首先以空白图片进入 .md ,则即使该字段应为 File <,它也会错误地将该字段推断为 String ./code>.使用新的API,我可以在 gatsby-node.js 中告诉盖茨比有关图像字段的信息:

If Gatsby get to the .md with the empty image first, it'll incorrectly infer that field as String, even though it should be File. With the new API, I can tell Gatsby about image field in gatsby-node.js:

exports.sourceNodes = ({ actions, schema }) => {
  const { createTypes } = actions
  createTypes(`
    type MarkdownRemarkFrontmatter {
      image: File
    }

    type MarkdownRemark implements Node {
      frontmatter: MarkdownRemarkFrontmatter
    }
  `)
}

这将确保 image 字段始终为文件类型,否则将为 null .

This'll guarantee the image field to always be of File type, otherwise it'll be null.

一些注意事项:

  • MarkdownRemark 这样的根节点必须实现 Node
  • 一个节点可以实现多个接口
  • 您必须按照自己的方式行事至相关领域.在此示例中,我必须声明 MarkdownRemarkFrontmatter 类型,然后将其传递给 MarkdownRemark 节点中的 frontmatter 字段.
  • 如果未指定,Gatsby将推断其余字段.在上面的示例中,由于我没有在 MarkdownRemarkFrontmatter 中指定 category 字段,因此Gatsby会像以前一样推断出该字段.
  • 找到这些类型( MarkdownRemark MarkdownRemarkFrontmatter )的最有用的方法是在graphiql中查找它们(默认为 localhost:8000/___ graphql )
  • Root nodes like MarkdownRemark has to implement Node
  • A node can implement multiple interface
  • You have to 'work your way' down to the relevant field. In this example, I have to declare the MarkdownRemarkFrontmatter type, then pass it to the frontmatter field in MarkdownRemark node.
  • Gatsby will infer the rest of the fields if not specified. In the example above, since I didn't specify the category field in MarkdownRemarkFrontmatter, it will be inferred by Gatsby just like before.
  • The most helpful way to find these types (MarkdownRemark, MarkdownRemarkFrontmatter) is to look for them in graphiql (default at localhost:8000/___graphql)

这篇关于如何给Gatsby提供GraphQL模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆