简体   繁体   中英

Problem using a generic object as an input type in a GraphQL schema Error: Schema must contain unique named types

I have a plugin that creates an object with {id: "XXX", text: "XXX"} when tags are created by the user. I am trying to get my apollo graphql server to accept this object as a type in my schema. I have tried many things but the one that makes the most sense to me is to create a type with that object shape and use it. That seems to work in the original type but not in the inputs (update and new). I get an error: Error: Schema must contain unique named types but contains multiple types named "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;

which then gets combined like

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

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

Is there a way to get my server to accept this object in the inputs or do I have to save as string and convert it on save and load? (ie "[{id: 'S', text: 'S'}]")

I guess what I was trying to create was a custom scalar (as opposed to built in scalars like string, int etc.) Changing my customQuestionOption to a scalar was all I needed to do. EDIT - see below

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;

This worked fine except the individual properties of the object weren't available to be queried. The real solution was to turn CustomQuestionOption back to a type to use in the query and to create another input (I called it InputCustomQuestionOption) and use that for the final inputs:

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM