Я сталкивался с этой ошибкой GraphQL в течение последнего дня или около того, и мне трудно определить, в чем проблема. Я надеюсь, что следующее имеет смысл ...
В моем проекте у меня есть следующие типы GraphQL; Анкета и вопрос, в котором Анкета содержит много Вопросов, и Вопрос принадлежит одной Анкете.
У меня есть следующие запросы: getQuestionnaires
(получает все Анкеты), getQuestionnaire
(получает одну Анкету по ее идентификатору ), getQuestions
(получает все вопросы, либо все вопросы в системе, либо вопросы к вопроснику, указав questionnaireId
).
Это тип вопросника (я оставил несколько атрибутов для краткости):
import {
GraphQLID,
GraphQLObjectType,
GraphQLNonNull,
} from 'graphql'
import QuestionType from './Question'
import QuestionResolver from '../resolver/question'
const QuestionnaireType: GraphQLObjectType = new GraphQLObjectType({
name: 'Questionnaire',
fields() {
return {
id: {
type: new GraphQLNonNull(GraphQLID),
},
// other literal attributes go here
questions: QuestionResolver.query.getQuestions,
}
},
})
export default QuestionnaireType
Как видите, атрибут questions
для Типа вопросника просто вызывает распознаватель для getQuestions
.
Это распознаватель для getQuestions
:
import {
GraphQLList,
GraphQLID
} from 'graphql'
import QuestionType from '../../type/Question'
export default {
type: GraphQLList(QuestionType),
description: 'Returns a list of questions',
args: {
questionnaireId: {
type: GraphQLID,
description: 'Questions that belong to this questionnaire',
},
},
async resolve(source: any, { questionnaireId = undefined }: any, ctx: any): Promise<any> {
// Based on the `questionnaireId` get the questions. If `undefined` get "all" questions.
},
}
Как видите, getQuestions
возвращает GraphQLList(QuestionType)
. Что приводит нас к типу вопроса:
import {
GraphQLID,
GraphQLObjectType,
GraphQLNonNull,
} from 'graphql'
import QuestionnaireType from './Questionnaire'
import QuestionnaireResolver from '../resolver/questionnaire'
const QuestionType: GraphQLObjectType = new GraphQLObjectType({
name: 'Question',
fields() {
return {
id: {
type: new GraphQLNonNull(GraphQLID),
},
questionnaire: QuestionnaireResolver.query.getQuestionnaire,
}
},
})
export default QuestionType
Хорошо. Все идет нормально. Этот код компилируется и запускается.
Однако с этим кодом есть проблема. Решатель getQuestions
принимает идентификатор вопросника в качестве параметра (questionnaireId
). Если идентификатор анкеты не передан (undefined
), он просто возвращает все вопросы в системе. Это означает, что в типе вопросника для атрибута questions
мы не хотим напрямую вызывать распознаватель getQuestions
, но мы хотим обернуть его в распознаватель, который извлекает source.id
(source
- это Анкета в этом контексте) и передайте ее в качестве аргумента для распознавателя getQuestions
. Если мы этого не сделаем, то при запросе вопросов в вопроснике всегда будут возвращаться все вопросы в системе, а это то, что нам не нужно.
Итак, мы заключаем решатель в решатель, который извлекает Идентификатор вопросника перед вызовом распознавателя getQuestions
. Наш тип вопросника теперь выглядит следующим образом:
import {
GraphQLID,
GraphQLObjectType,
GraphQLNonNull,
} from 'graphql'
import QuestionType from './Question'
import QuestionResolver from '../resolver/question'
const QuestionnaireType: GraphQLObjectType = new GraphQLObjectType({
name: 'Questionnaire',
fields() {
return {
id: {
type: new GraphQLNonNull(GraphQLID),
},
// other literal attributes go here
questions: {
type: GraphQLList(QuestionType),
async resolve(source: any, args: any, ctx: any): Promise<any> {
return QuestionResolver.query.getQuestions.resolve(
source,
{
questionnaireId: source.questionnaireId,
},
ctx
)
},
},
}
},
})
export default QuestionnaireType
Теперь мы завернули решатель getQuestions
, чтобы извлечь source.id
(т. Е. Идентификатор вопросника), чтобы мы всегда могли передать его в getQuestions
resolver (так как это то, что мы всегда хотим в этом контексте).
Однако, когда я делаю выше. Я получаю эту ошибку:
[Node] /Project/api/node_modules/graphql/type/definition.js:91
[Node] throw new Error("Expected ".concat((0, _inspect.default)(type), " to be a GraphQL type."));
[Node] ^
[Node]
[Node] Error: Expected undefined to be a GraphQL type.
[Node] at assertType (/Project/api/node_modules/graphql/type/definition.js:91:11)
[Node] at new GraphQLList (/Project/api/node_modules/graphql/type/definition.js:307:19)
[Node] at Object.GraphQLList (/Project/api/node_modules/graphql/type/definition.js:309:12)
[Node] at Object.<anonymous> (/Project/api/build/graphql/resolver/question/getQuestions.js:11:21)
[Node] at Module._compile (internal/modules/cjs/loader.js:936:30)
[Node] at Object.Module._extensions..js (internal/modules/cjs/loader.js:947:10)
[Node] at Module.load (internal/modules/cjs/loader.js:790:32)
[Node] at Function.Module._load (internal/modules/cjs/loader.js:703:12)
[Node] at Module.require (internal/modules/cjs/loader.js:830:19)
[Node] at require (internal/modules/cjs/helpers.js:68:18)
Я в тупике ....
В строке 11 из getQuestions
есть:
08: export default {
09: type: GraphQLList(QuestionType),
10: description: 'Returns a list of questions',
11: args: {
12: questionnaireId: {
13: type: GraphQLID,
14: description: 'Questions that belong to this questionnaire',
15: },
Я думаю, что у меня есть буквально перепробовал все, что приходит на ум, чтобы найти проблему. Мой проект biggi sh, и я использую эту технику в нескольких других местах без проблем, но по какой-то причине в этом конкретном сценарии она не компилируется.
Единственный способ, который я имею на данный момент, это использовать что-то вроде этого в распознавателе getQuestions
:
import {
GraphQLList,
GraphQLID
} from 'graphql'
import QuestionType from '../../type/Question'
export default {
type: GraphQLList(QuestionType),
description: 'Returns a list of questions',
args: {
questionnaireId: {
type: GraphQLID,
description: 'Questions that belong to this questionnaire',
},
},
async resolve(source: any, { questionnaireId = undefined }: any, ctx: any): Promise<any> {
// The workaround
const id = questionnaireId || source.id
},
}
Однако распознаватель getQuestions
не обязан смотреть на source
для извлечения аргументов, а также source
может технически быть другим объектом, чем Анкета, добавляющая больше сложности к распознавателю getQuestions
.
Любая помощь и понимание приветствуются.