GraphQL:对象名在解析器中定义,但不在架构中定义

GraphQL:对象名在解析器中定义,但不在架构中定义,graphql,apollo,Graphql,Apollo,我想用graphql定义一个突变 我的变异是得到一个对象作为论点。因此,我使用GraphQLObjectType在模式和解析器中定义了新对象 然而,我得到了这个错误: 错误:解析程序中定义了Agreement.name,但架构中未定义 有什么想法吗 这是我的模式定义 const typeDefs = ` type Agreement { id: Int } type Mutation { agreementsPost(agreement

我想用graphql定义一个突变

我的变异是得到一个对象作为论点。因此,我使用GraphQLObjectType在模式和解析器中定义了新对象

然而,我得到了这个错误:

错误:解析程序中定义了Agreement.name,但架构中未定义

有什么想法吗

这是我的模式定义

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);
        },
    }

这里有几件事需要解决。首先,要将对象用作参数,必须将其定义为模式中的
输入
(或
GraphQlinputObject类型
)——不能使用常规的
类型
(或
GraphQLObjectType
)作为参数

因此,您的类型定义需要如下所示:

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

input Agreement {
  id: Int
}
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) => {}
  },
}
如果您已经有一个
协议
类型,则需要将您的输入命名为其他名称。将
Input
附加到您的类型名称是一个很好的约定:

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

type Agreement {
  id: Int
}

input AgreementInput {
  id: Int
}
这应该足以允许您将
AgreementInput
对象作为参数传递给您的变体。您不需要将
协议
协议输入
添加到解析程序中(事实上,输入不是通过GraphQL“解析”的,因此无法为输入添加解析程序)

也就是说,您的解析器对象不需要合并
graphql
包提供的任何类型构造函数——Apollo在调用
makeExecutableSchema
时,从解析器和类型定义中为您构造一个
GraphQLSchema
对象

如果您的类型定义包括类型
Foo
Bar
,则您的
resolvers
对象可能如下所示:

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

input Agreement {
  id: Int
}
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) => {}
  },
}
请注意
解析器
对象中的每个属性如何匹配模式中定义的一种类型(包括查询和变异)。每个属性的值本身就是一个对象,每个属性映射到为该特定类型定义的字段之一。每个字段的值都是您的
resolve
函数

出现此错误的原因是,您实际上已告诉
makeExecutableSchema
向协议类型上的两个字段添加解析程序--
name
字段
--根据您的类型定义,这两个字段实际上都不在您的模式中


您可以阅读有关如何使用Apollo生成模式的更多信息。您可能会看到通过定义GraphQLSchema对象并将其传递给中间件,仅使用GraphQL.js“以编程方式”生成模式的示例。这两种方法都有优缺点,但使用
makeExecutableSchema
通常更容易,也不容易出错。无论哪种方式,知道如何以编程方式生成模式都是很好的,但不应将两者混合使用

在我的例子中,之所以发生这种情况,是因为非null的模式中存在不一致的。在我的变异中,我没有非空变异,而在对象模式中,它有非空变异。

我在从apollo server express的v1迁移到v2时遇到这个错误,这个错误与模式中没有定义上载有关。现在,在声明graphql模式时,可以使用选项set
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'
    }
  }
});
如果您的错误是上载特定的额外数据(与错误相关,而不是与Q代码相关),则出现此问题

你好,世界 我们在映射中定义解析程序,其中映射是 键对应于模式的类型。

最基本的“hello world”“错误地图”错误的示例

我的目的是错误的(在解析器定义下-使用
hello2
而不是
hello

服务器示例:

/*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.log('Server is running on localhost:4000'))
抛出错误:

[错误:Query.hello2在解析器中定义,但未在架构中定义]

解析器更改为
hello
(匹配到
hello
架构类型)以修复此错误:

相关:

  • 模式文档:
  • 伟大的导师:

好极了!很有效,非常感谢您的完美回复