在 GraphQL 架构中使用泛型对象作为输入类型时出现问题错误:架构必须包含唯一的命名类型

Posted

技术标签:

【中文标题】在 GraphQL 架构中使用泛型对象作为输入类型时出现问题错误:架构必须包含唯一的命名类型【英文标题】:Problem using a generic object as an input type in a GraphQL schema Error: Schema must contain unique named types 【发布时间】:2019-02-06 00:28:23 【问题描述】:

我有一个插件,当用户创建标签时,它会使用 id: "XXX", text: "XXX" 创建一个对象。我试图让我的 apollo graphql 服务器接受这个对象作为我模式中的一种类型。我尝试了很多事情,但对我来说最有意义的事情是创建一个具有该对象形状的类型并使用它。这似乎适用于原始类型,但不适用于输入(更新和新)。我收到一个错误:错误:架构必须包含唯一的命名类型,但包含多个名为“CustomQuestionOption”的类型。

const customQuestionTypeDefs = `
type CustomQuestionOption 
  id: ID,
  text: String


type CustomQuestion 
  id: ID!
  question: String
  questionType: String
  options: [CustomQuestionOption]
  required: Boolean


input UpdatedCustomQuestion 
  id: ID!
  question: String
  questionType: String
  options: [CustomQuestionOption]
  required: Boolean


input NewCustomQuestion 
  question: String
  questionType: String
  options: [CustomQuestionOption]
  required: Boolean


extend type Query 
  CustomQuestion(id: ID!): CustomQuestion!
  allCustomQuestions: [CustomQuestion]!


extend type Mutation 
  newCustomQuestion(input: NewCustomQuestion!): CustomQuestion!
  updateCustomQuestion(input: UpdatedCustomQuestion!): CustomQuestion!

`;

export default customQuestionTypeDefs;

然后像这样合并

const baseSchema = `
  schema 
    query: Query
    mutation: Mutation
  
`;

export const schema = makeExecutableSchema(
  typeDefs: [baseSchema, eventTypeDefs, sponsorshipItemTypeDefs, customQuestionTypeDefs, userTypeDefs],
  resolvers: merge(, eventResolvers, sponsorshipItemResolvers, customQuestionResolvers, userResolvers)
);

有没有办法让我的服务器在输入中接受这个对象,或者我必须保存为字符串并在保存和加载时转换它? (即“[id: 'S', text: 'S']”)

【问题讨论】:

Should I write two times each objects as 'input' and 'type' in a graphql schema file的可能重复 【参考方案1】:

我想我想要创建的是一个自定义标量(与字符串、int 等内置标量相反)。将我的 customQuestionOption 更改为标量就是我需要做的。 编辑 - 见下文

const customQuestionTypeDefs = `
scalar CustomQuestionOption 
  id: String,
  text: String


type CustomQuestion 
  id: ID!
  question: String
  questionType: String
  options: [CustomQuestionOption]
  required: Boolean


input UpdatedCustomQuestion 
  id: ID!
  question: String
  questionType: String
  options: [CustomQuestionOption]
  required: Boolean


input NewCustomQuestion 
  question: String
  questionType: String
  options: [CustomQuestionOption]
  required: Boolean


extend type Query 
  CustomQuestion(id: ID!): CustomQuestion!
  allCustomQuestions: [CustomQuestion]!


extend type Mutation 
  newCustomQuestion(input: NewCustomQuestion!): CustomQuestion!
  updateCustomQuestion(input: UpdatedCustomQuestion!): CustomQuestion!

`;

export default customQuestionTypeDefs;

除了无法查询对象的各个属性外,这一切正常。真正的解决方案是将 CustomQuestionOption 转回用于查询的类型并创建另一个输入(我称之为 InputCustomQuestionOption)并将其用于最终输入:

const customQuestionTypeDefs = `
type CustomQuestionOption 
  id: String,
  text: String


input InputCustomQuestionOption 
  id: String,
  text: String


type CustomQuestion 
  id: ID!
  question: String
  questionType: String
  options: [CustomQuestionOption]
  required: Boolean


input UpdatedCustomQuestion 
  id: ID!
  question: String
  questionType: String
  options: [InputCustomQuestionOption]
  required: Boolean


input NewCustomQuestion 
  question: String
  questionType: String
  options: [InputCustomQuestionOption]
  required: Boolean

【讨论】:

以上是关于在 GraphQL 架构中使用泛型对象作为输入类型时出现问题错误:架构必须包含唯一的命名类型的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL.js - 在 resolveType 函数中使用接口作为默认(后备)类型

如何在 AppSync GraphQL 架构中使用自定义输入类型?

对象作为突变中的输入变量:GraphQL - Apollo - React

对象数组的Graphql输入类型[重复]

使用 _id 字符串的 GraphQL 查询,对象 ID 存储在 MongoDB 中

无法使用 graphq-request 表示嵌套对象输入类型的数组