GraphQL:对象名称是在解析器中定义的,而不是在架构中定义的 [英] GraphQL : the object name is defined in resolvers, but not in schema

查看:82
本文介绍了GraphQL:对象名称是在解析器中定义的,而不是在架构中定义的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用graphql定义一个突变.

I want to define a mutation using graphql.

我的变异是将一个对象作为参数.因此,我使用GraphQLObjectType在架构和解析器中定义了新对象.

My mutation is getting an object as argument. So I defined the new Object in the schema and in the resolver using GraphQLObjectType.

但是我遇到此错误:

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

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

推荐答案

此处要解决的问题.首先,要将对象用作参数,必须在架构中将其定义为 input (或 GraphQLInputObjectType )-您不能使用常规的 type(或 GraphQLObjectType )作为参数.

Couple of things to fix here. First, to use an object as an argument, you have to define it as an input (or GraphQLInputObjectType) in your schema -- you cannot use a regular type (or GraphQLObjectType) as an argument.

因此您的类型定义需要看起来像这样:

So your type definitions need to look something like this:

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

input Agreement {
  id: Int
}

如果您已经具有 Agreement 类型,则需要用其他名称命名您的输入.只需将 Input 附加到您的类型名称是一个好习惯:

If you already have an Agreement type, you'll need to name your input something else. It's a good convention to just append Input to whatever your type name is:

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

type Agreement {
  id: Int
}

input AgreementInput {
  id: Int
}

这应该足以允许您传入 AgreementInput 对象作为突变的参数.您不需要向解析器添加 Agreement AgreementInput (实际上,GraphQL不会解析"输入,因此无法为输入添加解析器).

This should be sufficient to allow you to pass in an AgreementInput object as an argument to your mutation. You don't need to add Agreement or AgreementInput to your resolvers (in fact, inputs are not "resolved" by GraphQL, so adding a resolver for an input is not possible).

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

That said, your resolvers object should not need to incorporate any of the type constructors provided by the graphql package -- Apollo constructs a GraphQLSchema object from your resolvers and type definitions for you when you call makeExecutableSchema.

如果您的类型定义包括类型 Foo Bar ,则您的 resolvers 对象可能看起来像这样:

If your type definitions include the types Foo and Bar, your resolvers object might look something like this:

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 函数.

Notice how each property in the resolvers object matches one of the types defined in your schema (including Query and Mutation). The value of each of those properties is itself an object, with each property mapping to one of the fields defined for that particular type. Each field's value is your resolve function.

出现此错误的原因是,您已经有效地告诉 makeExecutableSchema 将解析器添加到协议类型的两个字段上- name 字段-根据您的类型定义,这两个字段实际上都不在您的架构中.

The reason for the error you're seeing is that you've effectively told makeExecutableSchema to add resolvers to two fields on the Agreement type -- name and fields -- neither of which are actually in your schema according to your type definitions.

您可以在此处.您可能会看到一些示例,其中通过定义GraphQLSchema对象并将其传递给中间件来仅使用GraphQL.js以编程方式"生成模式.两种方法都有优点和缺点,但是使用 makeExecutableSchema 通常更容易且更不易出错.无论哪种方式,最好都知道如何以编程方式生成模式,但是您不应该将两者混为一谈!

You can read more about how to generate a schema using Apollo here. You may see examples out there of generating a schema "programatically" using just GraphQL.js by defining a GraphQLSchema object and passing that to your middleware instead. There's pros and cons to both approaches, but using makeExecutableSchema is generally easier and less error-prone. Either way, it's good to know how to generate a schema programatically, but you should not mix the two!

这篇关于GraphQL:对象名称是在解析器中定义的,而不是在架构中定义的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆