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

tab*_*bim 10 apollo graphql

我想用graphql定义一个变异.

我的变异是将对象作为参数.所以我使用GraphQLObjectType在模式和解析器中定义了新的Object.

但是我收到此错误:

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

任何的想法 ?

这是我的架构定义

const typeDefs = `

    type Agreement {
        id: Int
    }

    type Mutation {
        agreementsPost(agreement: Agreement) : String
    }
`;
Run Code Online (Sandbox Code Playgroud)

这是我的解析器:

const appResolvers = {

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

       agreementsPost(root, args) {
            return axios.post("....").then(res => res.data);
        },
    }
Run Code Online (Sandbox Code Playgroud)

Dan*_*den 7

有几件事要在这里解决.首先,要将对象用作参数,必须将其定义为模式中的input(或GraphQLInputObjectType) - 不能使用常规type(或GraphQLObjectType)作为参数.

所以你的类型定义需要看起来像这样:

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

input Agreement {
  id: Int
}
Run Code Online (Sandbox Code Playgroud)

如果您已有Agreement类型,则需要将输入命名为其他内容.只需添加Input您的类型名称,这是一个很好的约定:

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

type Agreement {
  id: Int
}

input AgreementInput {
  id: Int
}
Run Code Online (Sandbox Code Playgroud)

这应该足以允许您将AgreementInput对象作为参数传递给您的变异.您不需要添加AgreementAgreementInput解析您的解析器(实际上,GraphQL没有"解析"输入,因此无法为输入添加解析器).

也就是说,您的解析器对象不需要包含graphql程序包提供的任何类型构造函数- Apollo GraphQLSchema会在您调用时为解析程序构造一个对象并为您定义类型定义makeExecutableSchema.

如果你的类型定义包括类型FooBar,你的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) => {}
  },
}
Run Code Online (Sandbox Code Playgroud)

注意resolvers对象中的每个属性如何匹配模式中定义的类型之一(包括查询和变异).每个属性的值本身就是一个对象,每个属性映射到为该特定类型定义的字段之一.每个字段的值都是您的resolve功能.

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

您可以在此处阅读有关如何使用Apollo生成模式的更多信息.您可能会看到通过定义GraphQLSchema对象并将其传递到中间件而使用GraphQL.js"以编程方式"生成模式的示例.两种方法都有利有弊,但使用makeExecutableSchema通常更容易,更不容易出错.无论哪种方式,最好知道如何以编程方式生成模式,但不要混淆两者!