GraphQL: имя объекта определяется в преобразователях, но не в схеме

Я хочу определить мутацию с помощью graphql.

Моя мутация получает объект в качестве аргумента. Итак, я определил новый объект в схеме и в преобразователе, используя GraphQLObjectType.

Однако я получаю эту ошибку:

Error: Agreement.name defined in resolvers, but not in schema

Любая идея ?

Вот мое определение схемы

const typeDefs = `

    type Agreement {
        id: Int
    }

    type Mutation {
        agreementsPost(agreement: Agreement) : String
    }
`;

А вот и мой резолвер:

const appResolvers = {

    Agreement: new GraphQLObjectType({
        name: 'Agreement',
        fields: {
            id: { type: GraphQLInt },
        }
    }),
Mutation: {

       agreementsPost(root, args) {
            return axios.post("....").then(res => res.data);
        },
    }
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Что такое Apollo Client и зачем он нужен?
Что такое Apollo Client и зачем он нужен?
Apollo Client - это полнофункциональный клиент GraphQL для JavaScript-приложений, который упрощает получение, управление и обновление данных в...
14
0
18 145
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Здесь нужно исправить пару вещей. Во-первых, чтобы использовать объект в качестве аргумента, вы должны определить его как input (или GraphQLInputObjectType) в своей схеме - вы не можете использовать обычный type (или GraphQLObjectType) в качестве аргумента.

Итак, определения вашего типа должны выглядеть примерно так:

type Mutation {
  agreementsPost(agreement: Agreement): String
}

input Agreement {
  id: Int
}

Если у вас уже есть тип Agreement, вам нужно будет назвать свой ввод другим именем. Хорошее соглашение - просто добавить Input к любому имени вашего типа:

type Mutation {
  agreementsPost(agreement: AgreementInput): String
}

type Agreement {
  id: Int
}

input AgreementInput {
  id: Int
}

Этого должно быть достаточно, чтобы позволить вам передать объект AgreementInput в качестве аргумента вашей мутации. Вам не нужно добавлять Agreement или AgreementInput к вашим преобразователям (фактически, входные данные не «разрешаются» GraphQL, поэтому добавление преобразователя для входа невозможно).

Тем не менее, ваш объект преобразователей не должен включать какие-либо конструкторы типов, предоставляемые пакетом graphql - Apollo создает объект GraphQLSchema из ваших преобразователей и определений типов, когда вы вызываете makeExecutableSchema.

Если ваши определения типов включают типы Foo и Bar, ваш объект resolvers может выглядеть примерно так:

const resolvers = {
  Foo: {
    someFooProperty: (foo, args, context, info) => {}
  },
  Bar: {
    someBarProperty: (bar, args, context, info) => {}
    someOtherBarProperty: (bar, args, context, info) => {}
  },
  Query: {
    someQuery: (root, args, context, info) => {}
  },
  Mutation: {
    someMutation: (root, args, context, info) => {}
  },
}

Обратите внимание, как каждое свойство в объекте resolvers соответствует одному из типов, определенных в вашей схеме (включая запрос и мутацию). Значение каждого из этих свойств само по себе является объектом, причем каждое свойство отображается в одно из полей, определенных для этого конкретного типа. Значение каждого поля - это ваша функция resolve.

Причина ошибки, которую вы видите, заключается в том, что вы фактически сказали makeExecutableSchema добавить преобразователи в два поля типа соглашения - name и fields - ни одно из которых на самом деле не присутствует в вашей схеме в соответствии с определениями вашего типа.

Вы можете узнать больше о том, как создать схему с помощью Apollo здесь. Вы можете увидеть примеры создания схемы «программно», используя только GraphQL.js, путем определения объекта GraphQLSchema и передачи его вместо этого промежуточному программному обеспечению. У обоих подходов есть свои плюсы и минусы, но использование makeExecutableSchema, как правило, проще и менее подвержено ошибкам. В любом случае хорошо знать, как создавать схему программно, но не следует смешивать их!

Отлично! это работает, большое спасибо за отличный ответ

Mohamed Taboubi 24.04.2018 15:43

В моем случае это происходит из-за наличия несогласован в схеме для ненулевого. в моей мутации у меня нет ненулевой мутации, тогда как в схеме объекта она имеет ненулевую мутацию.

Я столкнулся с этой ошибкой при переходе с v1 apollo-server-express на v2, ошибка была связана с тем, что загрузка не была определена в схеме. Теперь при объявлении схемы graphql вы можете использовать набор опций uploads: false

// GraphQL: Schema
const SERVER = new ApolloServer({
  typeDefs: typeDefs,
  resolvers: resolvers,
  introspection: true,
  uploads: false,
  playground: {
    endpoint: `http://localhost:3000/graphql`,
    settings: {
      'editor.theme': 'light'
    }
  }
});

Появляется для решения проблемы в этом случае, если ваша ошибка специфична для Uploads.

Дополнительные данные (относящиеся к ошибке - не к Q-коду).

Привет мир

We define our resolvers in a map, where the map's keys correspond to our schema's types. https://www.apollographql.com/docs/tutorial/resolvers/

Самый простой пример "Привет мир" этого ошибка "неправильная карта".

Я ошибся с цель (в определениях резолвера - используйте hello2 вместо hello).

Пример сервера graphql-yoga:

/*index.js*/
const { GraphQLServer } = require('graphql-yoga')

const typeDefs = `
  type Query {
    hello(name: String): String!
  }
`

const resolvers = {
  Query: {
    hello2: (_, { name }) => `Hello ${name || 'World'}`,
  },
}

const server = new GraphQLServer({ typeDefs, resolvers })
server.start(() => console.info('Server is running on localhost:4000'))

Выкинуть ошибку:

[Error: Query.hello2 defined in resolvers, but not in schema]

Измените решатель на hello (соответствует типу схемы hello), чтобы исправить эту ошибку:

Связанный:

Другие вопросы по теме