GraphQL :对象名称在解析器中定义,但不在模式中 [英] GraphQL : the object name is defined in resolvers, but not in schema

查看:27
本文介绍了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.

但是我收到此错误:

错误:在解析器中定义了协议名称,但在架构中未定义

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 对象作为参数传递给您的变更.您不需要向解析器添加 AgreementAgreementInput(实际上,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.

如果您的类型定义包括 FooBar 类型,您的 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>fields - 根据您的类型定义,它们实际上都不在您的架构中.

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.

您可以在此处阅读有关如何使用 Apollo 生成架构的更多信息.您可能会看到通过定义 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天全站免登陆