如何在多个类型上使用GraphQL片段

如何在多个类型上使用GraphQL片段,graphql,dry,gatsby,contentful,Graphql,Dry,Gatsby,Contentful,我有一个盖茨比项目,对两种不同类型的内容使用非常相似的GraphQL查询:常规页面和wiki文章 按段塞分页 export const query = graphql` query($slug: String!) { page: contentfulPage(slug: {eq: $slug}) { title slug body { remark: childMarkdownRemark { excerpt

我有一个盖茨比项目,对两种不同类型的内容使用非常相似的GraphQL查询:常规页面和wiki文章

按段塞分页

export const query = graphql`
  query($slug: String!) {
    page: contentfulPage(slug: {eq: $slug}) {
      title
      slug
      body {
        remark: childMarkdownRemark {
          excerpt
          html
          headings {
            value
            depth
          }
        }
      }
      updatedAt(formatString: "D. MMM YYYY")
      authors {
        name
        email
      }
    }
  }
`
export const query = graphql`
  query($slug: String!) {
    article: contentfulWikiArticle(slug: {eq: $slug}) {
      title
      slug
      body {
        remark: childMarkdownRemark {
          excerpt
          html
          headings {
            value
            depth
          }
        }
      }
      updatedAt(formatString: "D. MMM YYYY")
      authors {
        name
        email
      }
 +    section {
 +      title
 +      slug
 +    }
 +    subsection {
 +      title
 +      slug
 +    }
    }
  }
`
slug的维基文章

export const query = graphql`
  query($slug: String!) {
    page: contentfulPage(slug: {eq: $slug}) {
      title
      slug
      body {
        remark: childMarkdownRemark {
          excerpt
          html
          headings {
            value
            depth
          }
        }
      }
      updatedAt(formatString: "D. MMM YYYY")
      authors {
        name
        email
      }
    }
  }
`
export const query = graphql`
  query($slug: String!) {
    article: contentfulWikiArticle(slug: {eq: $slug}) {
      title
      slug
      body {
        remark: childMarkdownRemark {
          excerpt
          html
          headings {
            value
            depth
          }
        }
      }
      updatedAt(formatString: "D. MMM YYYY")
      authors {
        name
        email
      }
 +    section {
 +      title
 +      slug
 +    }
 +    subsection {
 +      title
 +      slug
 +    }
    }
  }
`
除了wiki文章的附加部分和小节外,查询是相同的。为了保持干燥,我如何将页面字段移动到一个单独的片段中,该片段也可以传播到wiki文章查询中,尽管其类型不同?GraphQL能否提供如下内容:

fragment pageFields on [ContenfulPage, ContenfulWikiArticle] {
  ...
}
允许用户为graphql模式设置他们自己的类型,最终使这个问题成为可能

如果用户能够控制模式,graphql始终是可能的,但由于最近的Gatsby更新,用户最终可以自己实现这一点

安装程序 为了建立一个简单的示例,我将在这样一个简单的文件夹上使用
gatsby transformer json

jsonFolder
  |--one.json { "type": "One", "name": "a", "food": "pizza" }
  `--two.json { "type": "Two", "name": "b", "game": "chess" }
并使用选项声明我的类型名称:

{
  resolve: `gatsby-transformer-json`,
  options: { 
    typeName: ({ object }) => object.type,
  },
},
现在我有两种类型是为我创建的。我可以在其中一个上创建片段,但不能同时在两个上创建:

export const name = graphql`
  fragment name on One {
    name
  }
`

export const pageQuery = graphql`
  query {
    one {
      ...name
    }
    two {
      ...name <-- ⚠️ throw type error
    }
  }
`
魔法就发生在这一行,其中
One
Two
实现了
JsonNode
(自定义接口)和
Node
(盖茨比接口)

现在我可以编写一个片段来实现
JsonNode
&这两种类型都适用

//blogpostemplate.js
从“React”导入React
从“盖茨比”导入{graphql}
导出默认值({data})=>{JSON.Stringify(data)}
export const name=graphql`
JsonNode上的片段名称{
名称
水平
}
`
export const pageQuery=graphql`
质疑{
一个{

我想问一个很重要的问题,你有没有发现这个问题呢?我恐怕还没有。我不确定你是否已经解决了,很难解释,但是如果我看到了源码,我就能以一种好的格式化的方式回答问题,但是考虑在组件文件夹中从LayOut.js制作一个“模板包装组件”,然后做一个“布局”。对于在组件中构建的有内容的字段,然后声明共享数据或重复为null的字段,然后导出查询并过滤共享数据或字段。之后还有一些步骤,例如,如果您仍然被卡住,请与我联系。@NickC感谢您的评论,但我真正想问的是GraphQL是否提供了本机wa我不太明白你的建议,但听起来有点老套。使用阿波罗将“天生”完成这项任务非常酷!正如你所说,相当多的设置,所以感谢你给出的详细答案。