如何在 GraphQL 中处理多种类型的数组(例如:不同的内容块)?

And*_*lts 6 contentful graphql

假设我有一个页面构建器字段,它引用了许多不同类型的内容块。

  • 视频
  • 引用
  • 广告

等等...

根据我的阅读,不鼓励在数组中使用多种类型。

但是在这种情况下你还能做什么呢?

有没有办法在 GraphQL 中处理这个问题?

有没有更好的方法来构造数据?

小智 10

You could define them as a union (or interface if all implementing types share common fields)

Union schema example:

type Query {
  blocks: [ ContentBlock! ]!
}

type Video {
  url: String!
}

type Quote {
  body: String!
  author: String
}

type Advertisement {
  src: String!
  backgroundColor: String
}


union ContentBlock = Video | Quote | Advertisement
Run Code Online (Sandbox Code Playgroud)

Interface schema example:

type Query {
  blocks: [ ContentBlock! ]!
}

type Video implements ContentBlock {
  id: ID!
  url: String!
}

type Quote implements ContentBlock {
  id: ID!
  body: String!
  author: String
}

type Advertisement implements ContentBlock {
  id: ID!
  src: String!
  backgroundColor: String
}


interface ContentBlock {
  id: ID!
}
Run Code Online (Sandbox Code Playgroud)

Example resolver:

{
  ContentBlock: {
    __resolveType (source) {
      if (source.url) return 'Video'
      if (source.src) return 'Advertisment'
      if (source.author || source.body) return 'Quote'
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Example query:

{
  blocks {
    ...on Video {
      url
    }
    ...on Quote {
      body
      author
    }
    ...on Advertisement {
      src
      backgroundColor
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

More reading on Unions and Interfaces in GraphQL


Dav*_*raz 1

我相信,您可以实现接口列表或联合列表(基于数据的性质以及是否存在重复字段)。在该接口/联合中,您将实现所有这些类型(视频、报价、广告)。然而,它适用于数据获取,但接口或联合不能用作输入类型。如果您想将其实现为输入类型,则需要使用例如 JSON 自定义标量https://github.com/taion/graphql-type-json

编辑:我不认为界面中的列表中有多种类型是不好的做法。您可以查看节点查询或在 Github api 上搜索https://developer.github.com/v4/query/