gpt4 book ai didi

graphql - 如何在多种类型上使用 GraphQL 片段

转载 作者:行者123 更新时间:2023-12-04 12:45:10 28 4
gpt4 key购买 nike

我有一个 Gatsby 项目,它对两种不同类型的内容进行了非常相似的 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
}
}
}
`

维基文章由 slug
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允许用户为 graphql 模式设置自己的类型,最终使这个问题成为可能。

It's always been possible with graphql if users have control of the schema, but thanks to the recent Gatsby update, users can finally implement this on their own.



设置

为了建立一个简单的例子,我将使用 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 注册一个新接口(interface)和 2 种类型。请注意 JsonNode包含两个 One 的公共(public)字段和 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 - 如何在多种类型上使用 GraphQL 片段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51269168/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com