如何在多种类型上使用GraphQL片段 [英] How to use GraphQL fragment on multiple types
本文介绍了如何在多种类型上使用GraphQL片段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一个Gatsby项目,它对两种不同类型的内容进行了非常相似的GraphQL查询:常规页面和维基文章。
分页
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
}
}
}
`
插件的Wiki文章
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] {
...
}
推荐答案
Gatsby recent release允许用户为图形QL架构设置自己的类型,最终使此问题成为可能。
如果用户拥有架构的控制权,使用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
}
}
`
让我们解决这个问题。
设置类型
我将使用一个名为createTypes
的新API注册一个新接口&为每个json注册两种类型。请注意,JsonNode
包含One
和Two
的公共字段:
exports.sourceNodes = ({ actions }) => {
const { createTypes } = actions
const typeDefs = `
interface JsonNode {
name: String
type: String!
}
type One implements Node & JsonNode {
name: String
type: String!
food: String
}
type Two implements Node & JsonNode {
name: String
type: String!
game: String
}
`
createTypes(typeDefs)
}
神奇之处在于这一行,One
&;Two
同时实现了JsonNode
(自定义接口)和Node
(Gatsby接口)。
type One implements Node & JsonNode { ... }
现在我可以编写实现JsonNode
&;的片段了。它对两种类型都有效。
// blogPostTemplate.js
import React from "react"
import { graphql } from "gatsby"
export default ({ data }) => <div>{JSON.Stringify(data)}</div>
export const name = graphql`
fragment name on JsonNode {
name
level
}
`
export const pageQuery = graphql`
query {
one {
...name <- 👍 works
}
two {
...name <- 👍 works
}
}
`
这需要一些设置,但如果您事先知道您的数据类型,可能是值得的,而且需要大量重复使用片段。
这篇关于如何在多种类型上使用GraphQL片段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文